Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计提醒

boxlang-web-developmentBoxlang 网络开发

Agent Skill

boxlang-web-development 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

188

周安装

8

GitHub Stars

公开资料未说明

下载量

66
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:boxlang-web-development(Boxlang 网络开发)
来源仓库:https://github.com/ortus-boxlang/skills
仓库路径:skills/boxlang-web-development
安装命令:
npx skills add https://github.com/ortus-boxlang/skills --skill boxlang-web-development
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ortus-boxlang/skills --skill boxlang-web-development

简介

BoxLang Web Development 围绕 Application.bx 构建 Web 应用生命周期。

  • 适用于开发 REST API、会话管理和 CSRF 防护等 Web 功能。
  • 支持 MiniServer(开发)和 CommandBox(生产)两种部署模式。
  • Application.bx 负责全局配置,包括路由、中间件和定时任务。
  • 建议结合 application-descriptor 技能处理多应用隔离和描述发现。

SKILL.md

BoxLang Web Development

Overview

BoxLang web applications revolve around Application.bx, which acts as the application lifecycle controller. The runtime handles HTTP requests through a well-defined lifecycle, with full support for REST, sessions, CSRF, SSE, and both MiniServer (dev) and CommandBox (production) deployment.

For a deep dive into multi-app isolation, descriptor discovery, and advanced Application.bx patterns, see the application-descriptor skill.

Application.bx

Application.bx lives at the web root and configures the entire application:

// Application.bx
class {

    // Application settings
    this.name            = "MyApp"
    this.sessionManagement = true
    this.sessionTimeout  = createTimeSpan( 0, 2, 0, 0 )  // 2 hours
    this.applicationTimeout = createTimeSpan( 1, 0, 0, 0 )  // 1 day
    this.setClientCookies = true

    // Java classpath additions
    this.javaSettings = {
        loadPaths: [ "lib/" ],
        loadColdFusionClassPath: false,
        reloadOnChange: false
    }

    // Datasource defaults
    this.datasource = "mainDB"

    // --- Lifecycle Events ---

    // Fires once when the application first starts
    boolean function onApplicationStart() {
        application.version = "1.0.0"
        application.config  = loadConfig()
        return true
    }

    // Fires before every request
    boolean function onRequestStart( required string targetPage ) {
        // Auth checks, request logging, CORS headers
        if ( !isAuthenticated() && !isPublicRoute( arguments.targetPage ) ) {
            location( url="/login", addToken=false )
        }
        return true
    }

    // Fires after every request
    void function onRequestEnd( required string targetPage ) {
        // Cleanup, audit logging
    }

    // Called when request target is a .bx file (optional — allows custom routing)
    void function onRequest( required string targetPage ) {
        include arguments.targetPage
    }

    // Fires when a new session starts
    boolean function onSessionStart() {
        session.cart    = []
        session.userId  = ""
        session.isLoggedIn = false
        return true
    }

    // Fires when a session ends
    void function onSessionEnd( required struct sessionScope, required struct appScope ) {
        auditService.recordLogout( arguments.sessionScope.userId )
    }

    // Global error handler
    boolean function onError( required any exception, required string eventName ) {
        errorService.log( arguments.exception )
        include "views/error.bxm"
        return true
    }

    // Missing template handler
    boolean function onMissingTemplate( required string targetPage ) {
        location( url="/404" )
        return true
    }

}

Request Scope and CGI Variables

// URL variables (?key=value)
var page = url.page ?: 1
var query = url.q ?: ""

// Form variables (POST body)
var username = form.username ?: ""
var password = form.password ?: ""

// CGI scope
var userAgent   = cgi.http_user_agent
var requestMethod = cgi.request_method  // GET, POST, PUT, DELETE
var remoteAddr  = cgi.remote_addr
var serverName  = cgi.server_name

// Request scope (per-request shared storage)
request.startTime = getTickCount()
request.userId    = session.userId

Handling Forms

// Process a form submission
if ( cgi.request_method == "POST" ) {
    // Validate
    if ( !len( trim( form.email ) ) ) {
        request.errors.append( "Email is required" )
    }

    if ( !request.errors.len() ) {
        userService.create({
            email    : form.email,
            username : form.username,
            password : hashPassword( form.password )
        })
        location( url="/dashboard", addToken=false )
    }
}

REST API Patterns

// REST endpoint using onRequest routing in Application.bx
void function onRequest( required string targetPage ) {
    var method  = cgi.request_method
    var path    = cgi.path_info
    var router  = new Router()

    router.get( "/api/users",      "handlers.UsersHandler", "index" )
    router.post( "/api/users",     "handlers.UsersHandler", "create" )
    router.get( "/api/users/:id",  "handlers.UsersHandler", "show" )
    router.put( "/api/users/:id",  "handlers.UsersHandler", "update" )
    router.delete( "/api/users/:id", "handlers.UsersHandler", "delete" )

    router.dispatch( method, path )
}

// Handler: handlers/UsersHandler.bx
class {

    function index() {
        var users = userService.findAll()
        renderJSON( users )
    }

    function show( required numeric id ) {
        var user = userService.findById( arguments.id )
        if ( isNull( user ) ) {
            httpStatus( 404 )
            renderJSON({ error: "Not found" })
            return
        }
        renderJSON( user )
    }

    function create() {
        var data = jsonDeserialize( getHTTPRequestData().content )
        var user = userService.create( data )
        httpStatus( 201 )
        renderJSON( user )
    }

}

// Helper functions
function renderJSON( required any data ) {
    bx:header name="Content-Type" value="application/json";
    writeOutput( jsonSerialize( arguments.data ) )
    abort
}

function httpStatus( required numeric code ) {
    bx:header statusCode=arguments.code;
}

HTTP Client

// Simple GET
var response = httpGet( "https://api.example.com/data" )
var data     = jsonDeserialize( response.fileContent )

// Full bx:http request
bx:http url="https://api.example.com/users" method="POST" result="apiResponse" {
    bx:httpparam type="header" name="Authorization" value="Bearer #token#"
    bx:httpparam type="header" name="Content-Type"  value="application/json"
    bx:httpparam type="body"   value=jsonSerialize({ name: "Ada", email: "ada@example.com" })
}

var response = jsonDeserialize( apiResponse.fileContent )

// HTTP with query string
bx:http url="https://api.example.com/search" method="GET" result="searcharesult" {
    bx:httpparam type="url" name="q"     value="boxlang"
    bx:httpparam type="url" name="limit" value="10"
}

// File download
bx:http url="https://example.com/report.pdf" method="GET" result="pdfResponse"
        getAsBinary="yes"
fileWrite( expandPath( "./downloads/report.pdf" ), pdfResponse.fileContent )

Session Management

// Set session values
session.userId    = user.getId()
session.username  = user.getUsername()
session.isLoggedIn = true
session.cart       = []

// Check session
if ( session.isLoggedIn ?: false ) {
    // Authenticated
}

// Invalidate session on logout
sessionInvalidate()
location( url="/login", addToken=false )

// Extend session programmatically
sessionRotate()

CSRF Protection

// Generate CSRF token (stores in session)
var token = csrfGenerateToken( "loginForm" )

// In your form (bxm template):
// <input type="hidden" name="csrfToken" value="#csrfGenerateToken('loginForm')#">

// Validate on POST
if ( !csrfVerifyToken( form.csrfToken, "loginForm" ) ) {
    httpStatus( 403 )
    writeOutput( "Invalid CSRF token" )
    abort
}

Server-Sent Events (SSE)

// SSE endpoint: sse/updates.bxs
bx:header name="Content-Type" value="text/event-stream";
bx:header name="Cache-Control" value="no-cache";
bx:header name="X-Accel-Buffering" value="no";

var i = 0
while ( i < 100 ) {
    var data = getLatestUpdates()
    writeOutput( "data: #jsonSerialize(data)##char(10)##char(10)#" )
    flush
    sleep( 1000 )
    i++
}

Output and Rendering

// Include a template
include "views/header.bxm"
include "views/user/profile.bxm"

// Save output to variable
var rendered = ""
savecontent variable="rendered" {
    include "views/email/welcome.bxm"
}

// Set response headers
cfheader( name="X-Custom-Header", value="myValue" )
cfcontent( type="application/pdf" )

// Redirect
location( url="/dashboard", addToken=false )
location( url="/login", statusCode=302 )

MiniServer Configuration (Development)

miniserver.json in the project root:

{
    "host": "localhost",
    "port": 8080,
    "webroot": "./www",
    "debug": true,
    "warmUpURLs": ["/"],
    "rewrites": {
        "enable": true,
        "config": "urlrewrite.xml"
    }
}

Start MiniServer:

boxlang-miniserver
# or via CommandBox
box server start

CommandBox Server Configuration (Production)

server.json:

{
    "name": "MyApp",
    "web": {
        "http": { "port": 8080 },
        "https": { "port": 8443, "enable": true },
        "webroot": "www"
    },
    "app": {
        "cfengine": "boxlang",
        "javaVersion": "openjdk21_jdk"
    },
    "jvm": {
        "heapSize": "512m",
        "maxHeapSize": "1024m",
        "args": "-Duser.timezone=UTC"
    },
    "env": {
        "DB_HOST": "localhost",
        "DB_NAME": "myapp"
    }
}

SOAP Web Services

BoxLang 1.8.0+ provides the soap() BIF for consuming SOAP 1.1/1.2 web services. It automatically parses WSDL documents and converts SOAP XML responses to BoxLang native types.

Basic SOAP Client

// Create client from WSDL URL
var ws = soap( "http://example.com/service.wsdl" )

// Invoke an operation with named parameters
var result = ws.invoke( "getCustomer", { customerId: 12345 } )
writeOutput( "Name: #result.customerName#" )

Client with Authentication and Timeout

var ws = soap( "http://example.com/service.wsdl" )
    .withBasicAuth( "apiUser", "secret" )
    .timeout( 30 )

var customer = ws.invoke( "getCustomer", { customerId: 42 } )

Custom Headers

var ws = soap( "http://secure.example.com/service.wsdl" )
    .header( "X-API-Key", "abc123" )
    .header( "X-Tenant-ID", "tenant001" )
    .timeout( 45 )

var result = ws.invoke( "getData" )

Service Inspection (Discover Operations)

var ws = soap( "http://example.com/service.wsdl" )

// List all available operations
var operations = ws.getOperations()
operations.each( ( op ) -> writeOutput( op & "<br>" ) )

// Get input parameter details for an operation
var info = ws.getOperationInfo( "createOrder" )
info.inputParameters.each( ( param ) -> {
    writeOutput( "#param.name# (#param.type#)<br>" )
})

Error Handling (SOAP Faults → BoxLang Exceptions)

try {
    var ws = soap( "http://example.com/service.wsdl" )
    var result = ws.invoke( "processOrder", { orderId: orderId } )
} catch ( "soap.Fault" e ) {
    writeOutput( "SOAP fault: #e.message#" )
} catch ( "soap.ConnectionError" e ) {
    writeOutput( "Connection failed: #e.message#" )
} catch ( any e ) {
    writeOutput( "Unexpected error: #e.message#" )
}

When to use soap() vs bx:http:

Use soap()Use bx:http / httpGet()
Enterprise/legacy SOAP servicesModern REST/JSON APIs
WSDL-defined contractsLightweight, fast communication
WS-Security requiredJSON preferred
Complex type mappingSimple HTTP calls

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.43%
按下载量换算24

Claude

30.79%
按下载量换算20

Cursor

18.95%
按下载量换算13

Gemini CLI

8.67%
按下载量换算6

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills