Solon Web 开发:四、认识请求上下文(Context)

Handler + Context 架构,是Solon Web 的基础。在 Context (org.noear.solon.core.handle.Context)里可以获取:

  • 请求相关的对象与接口
  • 会话状态相关的对象与接口
  • 响应相关的对象与接口

或者理解所有请求与响应相关的,都在它身上。关于架构方面,可以再看看《想法与架构笔记》

1、几种获取(或控制) Context 的方式

a) 通过 Controller 获取

@Controller
public class HelloController{
    @Mapping("/hello")
    public String hello(Context ctx){
        //可以注入 ctx:Context
        return "Hello " + ctx.paramOrDefault("name", "world");
    }
}

b) 通过 Handler 或 Filter 或 RouterInterceptor 接口方式获取

Solon.start(DemoApp.class, args, app->{
   app.get("/hello", ctx-> ctx.output("Hello " + ctx.paramOrDefault("name", "world"))); 
});

//或者,用以组件方式编写
@Mapping("/hello")
@Component
public class HelloHandler implements Handler{
    public void handle(Context ctx) throws Throwable{
        ctx.output("Hello " + ctx.paramOrDefault("name", "world"));
    }
}

c) 直接获取当前上下文(基于 ThreadLocal 实现)

Context ctx = Context.current();

d) 获取当前线程的上下文,进行跨线程传递(一般在异步场景才用到)

public class Demo {
    public void asyncDemo() {
        //获取当前线程的请求上下文
        Context ctx = Context.current();

        //跨线程传递当前请求上下文
        RunUtil.async(()->{
            try {
                ContextUtil.currentSet(ctx);

                //... Context.current() 有值...
            } finally {
                ContextUtil.currentRemove();
            }
        });
    }
}

2、关于 context-path 的配置(基于 pathNew 实现)

添加配置即可:(v1.11.2 后支持)

server.contextPath: "/test-service/" #原路径仍能访问

或者:('!' 开头。v2.6.3 后支持)

server.contextPath: "!/test-service/" #原路径不能访问

3、几个特殊属性

属性 说明 备注
ctx.mainHandler() 获取主请求处理 路由器没有登记时,则为 null(基本属于 404 了)
ctx.controller() 获取当前控制器实例 如果不是 MVC 处理,则为 null
ctx.action() 获取当前动作对象 如果不是 MVC 处理,则为 null
ctx.action().method() 获取当前动作的执行函数包装
ctx.errors 获取MVC处理异常 action 执行完成后才会有值
ctx.result 获取MVC处理结果 action 执行完成后才会有值
ctx.attr("output") 获取 string 输出内容 只要通过 ctx.output(str) 输出的都会有这个记录

提示:控制器里的 @Mapping 函数,即为 Action

4、请求相关的接口

请求相关接口 说明
-request()->Object 原始请求对象
-remoteIp() 获取远程ip(也可能是代理的ip)
-remotePort() 获取远程端口(也可能是代理的port)
-realIp()->String 获取客户端真实IP
-isMultipart()-bool 是否为分段内容
-isMultipartFormData()->bool 是否为分段表单数据
-method()->String 获取请求方式
-protocol()->String 获取请求协议
-protocolAsUpper()->String 获取请求协议并大写
-url()->String 获取请求的URL字符串
-uri()->URI 获取请求的URI
-path()->String 获取请求的URI路径
-pathNew(String) 设置新路径
-pathNew()->String 获取新路径,不存在则返回原路径
-pathMap(String)->Map<String,String> 获取请求的URI路径变量,根据路径表达式
-pathAsUpper()->String 获取请求的URI路径并大写
-pathAsLower()->String 获取请求的URI路径并小写
-userAgent()>String 获取请求的UA
-contentLength()->long 获取内容长度
-contentType()->String 获取内容类型
-queryString()->String 获取查询字符串
-accept()->String 获取 Accept 头信息
-body()->String 获取body内容
-body(String)->String 获取body内容,并按指定字符串解码
-bodyNew()->String 获取新的body
-bodyNew(String) 设置新的body
-bodyAsBytes()->byte[] 获取body内容为byte[]
-bodyAsStream()->InputStream 获取body内容为Stream
-paramValues(String)->String[] 获取参数数组
-param(String)->String 获取参数
-paramOrDefault(String, String)->String 获取参数,并给定默认值
-paramAsInt(String)->int 获取参数并转为int
-paramAsInt(String, int)->int 获取参数并转为int, 并给定默认值
-paramAsLong(String)->long 获取参数并转为long
-paramAsLong(String, long)->long 获取参数并转为long,并给定默认值
-paramAsDouble(String)->double 获取参数并转为double
-paramAsDouble(String, double)->double 获取参数并转为double,并给定默认值
-paramAsDecimal(String)->BigDecimal 获取参数并转为BigDecimal
-paramAsDecimal(String, BigDecimal)->BigDecimal 获取参数并转为BigDecimal,并给定默认值
-paramAsBean(Class<T>)->T 获取参数并转为Bean
-paramMap()->MultiMap<String> 获取所有参数集合
-paramNames()->Set<String> 获取所有参数名字集合
-file(String)->UploadedFile 获取上传文件,第一个
-fileMap()->MultiMap<UploadedFile> 获取所有上传文件集合
-fileValues(String)->UploadedFile[] 获取上传文件,可能有多个
-fileNames()->Set<String> 获取所有上传文件名字集合
-filesDelete() 删除所有上传的临时缓冲文件(如果有)
-cookie(String)->String 获取 cookie
-cookieOrDefaul(String, String)->String 获取 cookie, 并给定默认值
-cookieValues(String)->String[] 获取 cookie 数组
-cookieMap()->MultiMap<String> 获取所有 cookie 集合
-cookieNames()->Set<String> 获取所有 cookie 名字集合
-header(String)->String 获取 header
-headerOrDefault(String, String)->String 获取 header,并给定默认值
-headerValues(String)->String[] 获取 header 数组
-headerMap()->MultiMap<String> 获取所有 header 集合
-headerNames()->Set<String> 获取所有 header 名字集合

关于 MultiMap 接口的使用示例:

//for(遍历)
for(KeyValues<String> kv: ctx.paramMap()){ //headerMap(), cookieMap()
    String       val  = kv.getValue();  //单值
    List<String> val2 = ky.getValues(); //多值
}

//add(添加)
ctx.paramMap().add("list", "a1")
ctx.paramMap().add("list", "a2")

ctx.paramValues("list") -> String[] //获取多值

//put(替换)
ctx.paramMap().put("item", "a1")

ctx.param("item") -> String //获取单值

5、响应相关的接口

响应相关接口 说明
-response()->Object 原始响应对象
-charset(String) 设置字符集
-contentType(String) 设置内容类型
-contentTypeNew() 获取设置的新内容类型
-contentLength(long) 设置内容长度
-render(Object) 渲染数据(比如将对象渲染为 Json 并输出)
-render(String, Map) 渲染视图
-renderAndReturn(Object)->String 渲染数据并返回
-output(byte[]) 输出 字节数组
-output(InputStream) 输出 流对象
-output(String) 输出 字符串
-output(Throwable) 输出 异常对象
-outputAsJson(String) 输出为json文本
-outputAsHtml(String) 输出为html文本
-outputAsFile(DownloadedFile) 输出为文件
-outputAsFile(File) 输出为文件
-outputStream()->OutputStream 获取输出流
-outputStreamAsGzip()->GZIPOutputStream 获取压缩输出流
-flush() 冲刷
-headerSet(String, String) 设置响应 header
-headerAdd(String, String) 添加响应 header
-headerOfResponse(String) 获取响应 header
-headerValuesOfResponse(String) 获取响应 header 数组
-headerNamesOfResponse() 获取响应 header 所有名字
-cookieSet(String, String) 设置响应 cookie
-cookieSet(String, String, int) 设置响应 cookie
-cookieSet(String, String, String, int) 设置响应 cookie
-cookieSet(String, String, String, String, int) 设置响应 cookie
-cookieRemove(String) 移徐响应 cookie
-redirect(String) 302跳转地址
-redirect(String, int) 跳转地址
-forward(String) 服务端转换地址
-status() 获取输出状态
-status(int) 设置输出状态

6、会话相关的接口

会话相关接口 说明
-sessionState()->SessionState 获取 sessionState
-sessionId()->String 获取 sessionId
-session(String)->Object 获取 session 状态
-sessionOrDefault(String, T)->T 获取 session 状态(类型转换,存在风险)
-sessionAsInt(String)->int 获取 session 状态以 int 型输出
-sessionAsInt(String, int)->int 获取 session 状态以 int 型输出, 并给定默认值
-sessionAsLong(String)->long 获取 session 状态以 long 型输出
-sessionAsLong(String, long)->long 获取 session 状态以 long 型输出, 并给定默认值
-sessionAsDouble(String)->double 获取 session 状态以 double 型输出
-sessionAsDouble(String, double)->double 获取 session 状态以 double 型输出, 并给定默认值
-sessionSet(String, Object) 设置 session 状态
-sessionRemove(String) 移除 session 状态
-sessionClear() 清空 session 状态

7、其它查询

其它相关接口 说明
+current()->Context 获取当前线程的上下文
-getLocale()->Locale 获取地区
-setLocale(Locale) 设置地区
-setHandled(bool) 设置处理状态
-getHandled() 获取处理状态
-setRendered(bool) 设置渲染状态
-getRendered() 获取渲染状态
-attrMap()->Map 获取自定义特性并转为Map
-attr(String)->Object 获取上下文特性
-attrOrDefault(String, T)->T 获取上下文特性,并设定默认值
-attrSet(String, Object) 设置上下文特性
-attrSet(Map) 设置上下文特性
-attrClear() 清除上下文特性
-remoting()->bool 是否为远程调用
-remotingSet(bool) 设置是否为远程调用
-result:Object 用于在处理链中透传处理结果
-errors:Throwable 用于在处理链中透传处理错误
-controller()->Object 获取当前控制器
-action()->Action 获取当前动作
posted @ 2023-07-04 11:12  带刺的坐椅  阅读(127)  评论(0)    收藏  举报