zoukankan      html  css  js  c++  java
  • struts.i18n.encoding[转]

    下面我从一个例子来重新审视这个参数的作用.首先我们来做一个实验,看看改参数是否用在了请求流程,是否用在了返回流程.首先下载struts2.0所有的包,我们会得到一个blank的例子程序.

    首先有三个返回类型:
    Java代码 复制代码 收藏代码
    1. <constant name="struts.enable.DynamicMethodInvocation" value="true" />   
    2.     <constant name="struts.devMode" value="false" />   
    3. <constant name="struts.i18n.encoding" value="UTF-8" />   
    4. <constant name="struts.velocity.manager.classname" value="demo.DemoVelocityManager"/>   
    5.   
    6. <package name="/" namespace="/" extends="struts-default">   
    7.            
    8.         <action name="test" class="demo.HelloWorldAction">   
    9.             <result name="jsp">helloworld.jsp</result>   
    10.             <result name="velocity" type="velocity">helloworld.vm</result>   
    11.             <result name="freemarker" type="freemarker">helloworld.ftl</result>   
    12.         </action>   
    13.     </package>  
    Java代码  收藏代码
    1. <constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    2.     <constant name="struts.devMode" value="false" />  
    3. <constant name="struts.i18n.encoding" value="UTF-8" />  
    4. <constant name="struts.velocity.manager.classname" value="demo.DemoVelocityManager"/>  
    5.   
    6. <package name="/" namespace="/" extends="struts-default">  
    7.           
    8.         <action name="test" class="demo.HelloWorldAction">  
    9.             <result name="jsp">helloworld.jsp</result>  
    10.             <result name="velocity" type="velocity">helloworld.vm</result>  
    11.             <result name="freemarker" type="freemarker">helloworld.ftl</result>  
    12.         </action>  
    13.     </package>  



    接着定义action:

    Java代码 复制代码 收藏代码
    1. /**  
    2.  *   
    3.  * @author ahuaxuan  
    4.  * @date 2008-6-8  
    5.  * @version $id$  
    6.  */  
    7. public class HelloWorldAction {   
    8.   
    9.     private String requestEncoding;   
    10.        
    11.     private String responseEncoding;   
    12.        
    13.     public void check() {   
    14.         requestEncoding = ServletActionContext.getRequest().getCharacterEncoding();   
    15.         responseEncoding = ServletActionContext.getResponse().getCharacterEncoding();   
    16.     }   
    17.     public String doJsp() {   
    18.         check();   
    19.         return "jsp";   
    20.     }   
    21.        
    22.     public String doVelocity() {   
    23.         check();   
    24.         return "velocity";   
    25.     }   
    26.        
    27.     public String doFreemarker() {   
    28.         check();   
    29.         return "freemarker";   
    30.     }   
    31. }  
    Java代码  收藏代码
    1. /** 
    2.  *  
    3.  * @author ahuaxuan 
    4.  * @date 2008-6-8 
    5.  * @version $id$ 
    6.  */  
    7. public class HelloWorldAction {  
    8.   
    9.     private String requestEncoding;  
    10.       
    11.     private String responseEncoding;  
    12.       
    13.     public void check() {  
    14.         requestEncoding = ServletActionContext.getRequest().getCharacterEncoding();  
    15.         responseEncoding = ServletActionContext.getResponse().getCharacterEncoding();  
    16.     }  
    17.     public String doJsp() {  
    18.         check();  
    19.         return "jsp";  
    20.     }  
    21.       
    22.     public String doVelocity() {  
    23.         check();  
    24.         return "velocity";  
    25.     }  
    26.       
    27.     public String doFreemarker() {  
    28.         check();  
    29.         return "freemarker";  
    30.     }  
    31. }  


    访问:
    http://localhost:8080/demo/test!jsp.action

    Java代码 复制代码 收藏代码
    1. 页面输出:Languages   
    2. •   requestEncoding:UTF-8    
    3. •   responseEncoding:ISO-8859-1   
    Java代码  收藏代码
    1. 页面输出:Languages  
    2. •   requestEncoding:UTF-8   
    3. •   responseEncoding:ISO-8859-1   



    http://localhost:8080/demo/test!freemarker.action

    Java代码 复制代码 收藏代码
    1. 页面输出:Languages   
    2. •   requestEncoding:UTF-8    
    3. •   responseEncoding:ISO-8859-1   
    Java代码  收藏代码
    1. 页面输出:Languages  
    2. •   requestEncoding:UTF-8   
    3. •   responseEncoding:ISO-8859-1   



    http://localhost:8080/demo/test!velocity.action

    Java代码 复制代码 收藏代码
    1. 页面输出:Languages   
    2. •   requestEncoding:UTF-8    
    3. •   responseEncoding:ISO-8859-1   
    Java代码  收藏代码
    1. 页面输出:Languages  
    2. •   requestEncoding:UTF-8   
    3. •   responseEncoding:ISO-8859-1   



    看上去返回流的编码没有变化,都是iso-8859-1.
    struts.i18n.encoding换成GBK之后,3个页面的requestEncoding:都变成了requestEncoding:GBK,也就是该参数确实用在了请求流程中.
    而且response的encoding还是iso-8859-1,看到这个结果可能有人会产生疑惑,不是说这个参数可以用在返回流中的吗,为什么没有体现出来呢?

    其 实问题出在一个时间上,但是请大家看看HelloWorldAction里的代码,其实是有问题的,因为在check方法是在action里的方法里调用 的.而这个时候没有执行到result,struts2.0会在result中会设置response的一些参数(如果需要设置的话),所以这个时候的 response中的encoding其实不是response最终的encoding.如何才能看到response中最终的encoding呢,只有 在result被执行之后.

    于是下面我们写一个filter.如下:

    Java代码 复制代码 收藏代码
    1. public void doFilter(ServletRequest req, ServletResponse res,   
    2.             FilterChain fc) throws IOException, ServletException {   
    3.         fc.doFilter(req, res);   
    4.         System.out.println("responseEncoding : " + res.getCharacterEncoding());   
    5.     }  
    Java代码  收藏代码
    1. public void doFilter(ServletRequest req, ServletResponse res,  
    2.             FilterChain fc) throws IOException, ServletException {  
    3.         fc.doFilter(req, res);  
    4.         System.out.println("responseEncoding : " + res.getCharacterEncoding());  
    5.     }  



    然后在web.xml中配置在struts2的filter之前:

    Java代码 复制代码 收藏代码
    1. <filter-mapping>   
    2.         <filter-name>encode</filter-name>   
    3.         <url-pattern>/*</url-pattern>   
    4. </filter-mapping>   
    5.   
    6. <filter-mapping>   
    7.         <filter-name>struts2</filter-name>   
    8.         <url-pattern>/*</url-pattern>   
    9.     </filter-mapping>  
    Java代码  收藏代码
    1. <filter-mapping>  
    2.         <filter-name>encode</filter-name>  
    3.         <url-pattern>/*</url-pattern>  
    4. </filter-mapping>  
    5.   
    6. <filter-mapping>  
    7.         <filter-name>struts2</filter-name>  
    8.         <url-pattern>/*</url-pattern>  
    9.     </filter-mapping>  



    然后分别请求

    http://localhost:8080/demo/test!jsp.action

    Java代码 复制代码 收藏代码
    1. •   控制台输出:   
    2. •   responseEncoding:UTF-8  
    Java代码  收藏代码
    1. •   控制台输出:  
    2. •   responseEncoding:UTF-8  



    http://localhost:8080/demo/test!freemarker.action

    Java代码 复制代码 收藏代码
    1. 控制台输出:   
    2. •   responseEncoding:GBK  
    Java代码  收藏代码
    1. 控制台输出:  
    2. •   responseEncoding:GBK  



    http://localhost:8080/demo/test!velocity.action

    Java代码 复制代码 收藏代码
    1. 控制台输出:   
    2. •   responseEncoding:GBK  
    Java代码  收藏代码
    1. 控制台输出:  
    2. •   responseEncoding:GBK  


    由此可见在freemarker和velocity中struts.i18n.encoding确实被用来作为response返回流中content-type的charset值.

    那么为什么jsp不是这样的呢.
    因为jsp并不是模板,而是一个类,在真正运行的时候,servlet容器会把jsp编译成一个类.我们的HelloWorld.jsp就变成了HelloWorld_jsp.java,在这个类中我们可以看到如下代码:

    Java代码 复制代码 收藏代码
    1. try {   
    2.       _jspxFactory = JspFactory.getDefaultFactory();   
    3.       response.setContentType("text/html; charset=UTF-8");   
    4.       pageContext = _jspxFactory.getPageContext(this, request, response,   
    5.                 nulltrue8192true);   
    6.       _jspx_page_context = pageContext;  
    Java代码  收藏代码
    1. try {  
    2.       _jspxFactory = JspFactory.getDefaultFactory();  
    3.       response.setContentType("text/html; charset=UTF-8");  
    4.       pageContext = _jspxFactory.getPageContext(this, request, response,  
    5.                 null, true, 8192, true);  
    6.       _jspx_page_context = pageContext;  

    修改jsp中@page标签中的charset为GBK之后,控制台也输出了responseEncoding:GBK
    这说明,在jsp中,返回流的参数是由jsp的@page标签指定的,而不是有truts.i18n.encoding指定的.

    由 此可见, struts.i18n.encoding确实用在了请求和返回两个阶段,而且在返回阶段不同的view技术可能使用或者不使用 struts.i18n.encoding,freemarker和velocity会以该值作为返回流的charset,而jsp会以页面上的 @page标签中的charset作为返回流的charset.

    至于源代码,它们分别在VelocityResult,freemarkermanager,dispatcher, FilterDispatcher,大家有兴趣可以自行查看.

    对 于之前误导大家认为该参数只用在返回流程中,我向大家说一声对不起.从这件事情中我也学习到很多,尤其是态度上,之前做实验的时候发现这个参数用在一个地 方,便认为它只会用在这个地方,但是事实上这种想法是不对的,它用在一个地方不代表不能用在另外一个地方.我们应该抱着更为严谨的态度去看待所有的问题, 其实当时只要在源码里search “struts.i18n.encoding”这个字符串就会立刻得到完整的结论,但是正因为自己不严谨的态度导致之前作出了片面的结论.

    最后共享一些我放在之前放在一边的座右铭:态度决定高度,所以不管做什么事情都要先端正自己的态度,希望能与大家共勉.

    附,由于ahuaxuan水平有限,很有可能还是没有挖掘出更深层次的见解,希望您能多指正.
  • 相关阅读:
    Codeforces Round #649 (Div. 2) D. Ehab's Last Corollary
    Educational Codeforces Round 89 (Rated for Div. 2) E. Two Arrays
    Educational Codeforces Round 89 (Rated for Div. 2) D. Two Divisors
    Codeforces Round #647 (Div. 2) E. Johnny and Grandmaster
    Codeforces Round #647 (Div. 2) F. Johnny and Megan's Necklace
    Codeforces Round #648 (Div. 2) G. Secure Password
    Codeforces Round #646 (Div. 2) F. Rotating Substrings
    C++STL常见用法
    各类学习慕课(不定期更新
    高阶等差数列
  • 原文地址:https://www.cnblogs.com/cjunj/p/2169164.html
Copyright © 2011-2022 走看看