zoukankan      html  css  js  c++  java
  • Webx相框:RequestContext详细说明

    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:interceptors
    xmlns="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:interceptors
    xmlns="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訪问。

    @Autowired
    ParserRequestContext 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">
    


    entity编码。

    默认情况下,框架假设发现当前的charset无法表示请求中的字符时,就会将參数替换成entity编码,比方&#20320;&#22909;

    能够通过以下的代码关闭:

    <parser unescapeParameters="false">
    


    获取自己定义类型的參数值。

    MyEnum myEnum = params.getObjectOfType("myparam", MyEnum.class);
    


    假设须要获取日期參数。在配置中增加以下的代码:

    <parser>
    <property-editor-registrar
    class="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两种操作。

    @Autowired
    BufferedRequestContext buffered;
    @Autowired
    HttpServletResponse response;
    ...
    PrintWriter out = response.getWriter();
    buffered.pushBuffer(); // 创建新buffer,并压入栈顶
    out.print("world"); // 在新 buffer 中写入
    String content = buffered.popCharBuffer(); // 弹出顶层 buffer
    out.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:handler
    class="com.alibaba.citrus.service.requestcontext.rewrite.support.UrlNormalizer"
    />
    

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    视图创建
    根据表格作业题
    表格 作业题练习
    创建表格 练习题
    聚合函数、数学函数、日期时间函数
    接口自动化框架
    python+request+Excel 几十份接口测试用例一起自动化测试的接口测试框架
    python3 函数
    pip源头
    爬虫
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4865730.html
Copyright © 2011-2022 走看看