Webx框架:RequestContext详解
来源:互联网 发布:mac清理垃圾的软件 编辑:程序博客网 时间:2024/06/15 18:13
RequestContext
RequestContext可以看成request和response的合体。多个RequestContext还可以串起来,就像Filter链条一样。每个外层RequestContext都会在内层RequestContext的基础上增加功能。在设计模式中这叫装饰器。
RequestContext种类有basic/buffered/lazy-commit/parser/rewrite/session/set-locale功能。后面还会具体介绍。
下面是配置方法:
<services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts"><basic /><buffered /><lazy-commit /><parser /><set-locale defaultLocale="zh_CN" defaultCharset="UTF-8" /><!-- Optional -<session /><rewrite />--></services:request-contexts>
RequestContext之间是有依赖关系的,比如session依赖于basic。框架会自动根据依赖关系排序RequestContext,所以开发的时候可以不考虑顺序。
访问特定的RequestContext。如果想要通过ParserRequestContext获取上传的文件信息怎么做呢?可以通过findRequestContext获取文件信息。
ParserRequestContext parserRequestContext =RequestContextUtil.findRequestContext(request, ParserRequestContext.class);ParameterParser params = parserRequestContext.getParameters();FileItem myfile = params.getFileItem("myfile");String filename = myfile.getName();InputStream istream = myfile.getInputStream();
RequestContext种类
BasicRequestContext。基础RC,它可以包含多个拦截器。配置方法如下。
<basic><request-contexts:interceptorsxmlns="http://www.alibaba.com/schema/services/request-contexts/basic/interceptors"><interceptor class="...Interceptor1" /><interceptor class="...Interceptor2" /></request-contexts:interceptors></basic>
不管有没有声明,BasicRC总是会启用一个默认拦截器。默认拦截器主要是一些安全检查,避免Http Header Value中出现CRLF,status message增加html escape,限制cookie的总大小。下面这个例子给默认拦截器增加参数。
<request-contexts:interceptorsxmlns="http://www.alibaba.com/schema/services/request-contexts/basic/interceptors"><response-header-security-filter maxSetCookieSize="5K" /></request-contexts:interceptors>
set-locale会将默认的Locale和默认的字符集保存在ThreadLocal中,调用框架提供的StringEscapeUtils.escapeURL,TemplateService都会根据当前线程的Locale和字符集自动编码解码。TemplateService会根据Locale寻找对应的模板文件,比如TestPage_zh_CN.vm。
set-locale参数:
<set-locale defaultLocale="..."defaultCharset="..."inputCharsetParam="_input_charset"outputCharsetParam="_output_charset"paramKey="_lang" 持久Locale和字符集的query参数名sessionKey="_lang" /> 持久Locale和字符集的session名
parser用于解析请求。通常情况下使用下面的配置就足够了。
<services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts"><parser />...</services:request-contexts><services:upload sizeMax="5M" fileSizeMax="2M" />
上面这段代码能处理所有请求包括get请求,post请求,文件上传post请求。
通过ParserRequestContext访问。
@AutowiredParserRequestContext parser;...String s = parser.getParameters().getString("myparam");parser.getParameters().getBoolean("myparam");parser.getParameters().getString("myparam", "default_value");parser.getParameters().getFileItem("myfile");
访问Cookie。
parser.getCookies().getString("mycookie");
upload标签的参数。
<services:upload sizeMax="5M"fileSizeMax="2M"repository="/tmp"sizeThreshold="10K"keepFormFieldInMemory="true" />
repository上传文件临时文件夹,是ResourceLoader的装载路径而不是物理路径。
sizeThreshold,小于这个大小的文件将保存在内存中。
keepFormFieldInMemory,是否将表单中的字段保存在内存中。默认为false。
手动解析上传文件的请求。首先关闭自动解析。
<parser autoUpload="false">
然后在需要的时候调用parseUpload。
parser.getParameters().parseUpload();
还可以指定不同的参数。
UploadParameters params = new UploadParameters();params.applyDefaultValues();params.setSizeMax(new HumanReadableSize("10M"));params.setFileSizeMax(new HumanReadableSize("1M"));params.setRepository(new File("mydir"));parser.getParameters().parseUpload(params);
parser中获取参数是非常灵活的,请看下面的例子,它们都为了获取MyProductId。
request.getParameter("MyProductId");request.getParameter("myProductId");request.getParameter("my_product_id");request.getParameter("MY_PRODUCT_ID");request.getParameter("MY_productID");
如果不需要这种灵活性,可以在配置中关闭:
<parser caseFolding="none">
trim。默认情况下parser会对所有的参数进行trim,如果不需要这种操作,可以在配置中关掉。
<parser trimming="false">
可以通过下面的代码关闭:
<parser unescapeParameters="false">
获取自定义类型的参数值。
MyEnum myEnum = params.getObjectOfType("myparam", MyEnum.class);
如果需要获取日期参数,在配置中加入下面的代码:
<parser><property-editor-registrarclass="com.alibaba.citrus.service.configuration.support.CustomDateRegistrar"p:format="yyyy-MM-dd" p:locale="zh_CN" p:timeZone="GMT+8" /></parser>
如果类型转换出错,有两种处理方式,一种是保持安静,另外一种是抛出异常。
保持安静的情况下,如果类型转传出错,会使用默认值。
下面这段配置目的是如果转换出错,则抛出异常。
<parser converterQuiet="false">
GET请求中的中文参数。标准规定URL中的中文字符必须使用UTF8进行编码,但是并不是所有的厂商都遵循这种规定。
parser将URL中的参数使用input_charset进行解码。除了这种默认的解码方式,还提供了另外的备用方法。
使用servlet原本的解码机制。
<parser useServletEngineParser="true" />
servlet原本的解码机制不会根据set-locale中指定的编码,而是使用web容器的配置文件中指定的编码方式。
使用固定解码方式。
<parser URIEncoding="UTF-8" useBodyEncodingForURI="false" />
过滤请求参数。比如下面的代码限制了上传文件的扩展名。
<parser><filters><parser-filters:uploaded-file-whitelist extensions="jpg, gif, png" /></filters></parser>
buffered。在webx中,有screen、control、layout,它们都代表输出的页面。layout可以嵌套screen和control,screen可以嵌套control,control可以嵌套另外的control。在嵌套的时候,内层页面渲染的内容都会暂存在内存中,等到外层页面需要的时候再输出到自己的页面中。webx中有buffer栈,每个组件在渲染之前都会在栈中增加新的buffer,渲染的内容都会保存在栈顶buffer中,渲染完成之后弹出buffer栈。
提交时框架会检查buffer栈中是否只有一个缓冲区,如果不是就报错。
buffered配置方法:
<buffered />
不需要任何参数。
操作BufferedRequestContext,下面的例子演示了push和pop两种操作。
@AutowiredBufferedRequestContext buffered;@AutowiredHttpServletResponse response;...PrintWriter out = response.getWriter();buffered.pushBuffer(); // 创建新buffer,并压入栈顶out.print("world"); // 在新 buffer 中写入String content = buffered.popCharBuffer(); // 弹出顶层 bufferout.print("hello, ");out.print(content); // 写入较低层的 buffer
如果调用了getWriter就要通过popCharBuffer获取内容,如果调用了getOutputStream就要通过popByteBuffer获取内容。
关闭buffer机制。一般情况下不需要关闭,不过有时候需要生成很大的一个文件比如pdf、excel等,并且生成所消耗的时间也很长,如果有buffer,那么用户需要等到文件生成完毕之后才能开始下载,这种延迟肯定是不能接受的。如果网站里面没有组件嵌套,那么buffer也可以关闭以提高性能。
lazy-commit拦截response对象中的某些方法,阻止渲染内容被自动提交。当请求处理完成后再提交。和buffered配合使用效果更佳。如果没有buffered那么当缓冲区中的内容达到8K之后就会自动提交。
lazy-commit配置方法,没有任何参数。
<lazy-commit />
LazyCommitRequestContext提供了一些接口可以获取当前请求是否出错,是否重定向,状态码是什么
rewrite。非常类似于Apache中的mod_rewrite。它目的是将请求的URL映射到内部的URL。
rewrite是一个web应用,因此被匹配的URL是servletPath + pathInfo。
rewrite执行过程是先检查pattern是否匹配,如果匹配,再各个检查condition是否都满足,如果不满足就检查下一条rule。如果都满足,就执行substitution和handler。
servletPath和pathInfo。比如一个Servlet挂在/test/abc的URL上,那么一个URL/test/abc/ddd的servletPath就是/test/abc,pathInfo就是/ddd。
规则匹配的时候使用正则表达式,有专门的书,这里就不介绍了。
下面是rewite的配置例子。rule表示需要匹配的URL,condition表示匹配之后需要检查的条件,substitution表示替换规则,handler表示使用自定义方法更灵活地替换URL。
<services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts"><rewrite><!-- rule 1 --><rule pattern="..."><condition test="..." pattern="..." flags="..." /><condition test="..." pattern="..." flags="..." /><substitution uri="..." flags="..."><parameter key="..." value="..." /><parameter key="..." value="..." /><parameter key="..." value="..." /></substitution><handlers><rewrite-handlers:handler class="..." /></handlers></rule><!-- rule 2 --><rule pattern="..."></rule><!-- rule 3 --><rule pattern="..."></rule></rewrite>...</services:request-contexts>
condition用法例子。pattern属性也是使用正则表达式。
<condition test="%{SERVER_NAME}:%{SERVER_PORT}" pattern="www.(\w+).com:8080" /><condition test="%{QUERY:x}" pattern="!1" /><condition test="%{QUERY:y}" pattern="2" />
substitution例子。
<substitution uri="/%1/new_$1\.htm" />$1表示rule中regex group,%1表示最后一个匹配的condition中的regex group。
替换参数。替换之后,其他参数都会被删除。
<substitution><parameter key="ext" value="$1" /><parameter key="host" value="%1" /><parameter key="count"><value>1</value><value>2</value><value>3</value></parameter></substitution>
当一条rule规则替换完成之后,默认会继续执行后续的rule,使用已经替换的URL和参数继续匹配。
substitution中的flag可以是下面的参数:
- L last:停止匹配
- C chain:串接rule,就是默认行为
- QSA qsappend:保留原来的请求参数
- R=301:永久重定向
- R=302:临时重定向
301跳转用于SEO。
多个参数使用逗号隔开。
重定向例子:
<substitution uri="/new_hello.htm" flags="L,R,QSA" /><substitution uri="http://www.other-site.com/new_hello.htm" flags="L,R" />
handler。用于弥补正则表达式的不足。正则只能执行简单的替换,对于更加复杂的功能就需要用到handler。
webx框架提供URL规格化的handler。
<rewrite-handlers:handlerclass="com.alibaba.citrus.service.requestcontext.rewrite.support.UrlNormalizer"/>
- Webx框架:RequestContext详解
- Webx框架:Valve详解
- webx—Session框架详解
- RequestContext
- RequestContext
- website/webx框架学习
- Webx框架:依赖注入
- Webx框架:Pipeline简介
- Webx框架:ResourceLoader
- Webx框架:AutoConfig
- Webx框架:会话管理
- Webx框架:表单验证
- Webx框架指南
- webx 框架入门一
- webx框架-依赖注入
- webx框架-启动分析
- webx框架和SeaJS学习
- Webx框架指南(转载)
- vc++6.0按回车或ESC程序关闭
- HDU 1978
- Sharepoint
- Android学习笔记-EditText&TextView&Button&菜单栏
- c#线程间传递参数
- Webx框架:RequestContext详解
- 平凡的开始
- VF(简单)
- 风河从VxWorks5.5到VxWorks6.6介绍,破解
- usb device over current status detected
- General Type Categories_Learning Python
- MapReduce总体架构分析
- 循环赛日程表(递归法)
- sort命令