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水平有限,很有可能还是没有挖掘出更深层次的见解,希望您能多指正.
  • 相关阅读:
    unity vscode 断点问题
    unity Prefab 序列化一个小问题。
    公司有同事中病毒
    有点愧疚,今天把unity官方骗了...
    网络处理,发送约定
    (转载)MonoBehaviour的事件和具体功能总结
    控制台输出乱码问题
    vs遇到的字符串问题
    cmake的下载和安装
    三消设计思路, 通过配置文件搞定一切。
  • 原文地址:https://www.cnblogs.com/cjunj/p/2169164.html
Copyright © 2011-2022 走看看