struts2+freemarker中文参数乱码问题很简单的一个登录页面,获取用户名之后直接返回用户名,然后发现中文用
struts2+freemarker中文参数乱码问题
很简单的一个登录页面,获取用户名之后直接返回用户名,然后发现中文用户名返回之后都是乱码
这是什么原因? 加了一个过滤器,在过滤器里用request获取参数值已经是乱码了。。。
网上找了各种方法都是不行,过滤器修改request的编码,改配置文件,都尝试过了。
贴一下现在的配置,
struts.properties
struts.devMode=false
struts.enable.DynamicMethodInvocation=true
struts.i18n.reload=true
struts.ui.theme=simple
struts.locale=zh_CN
struts.i18n.encoding=UTF-8
struts.serve.static.browserCache=false
struts.url.includeParams=none
freemarker.properties
locale=zh_CN
default_encoding=utf-8
number_format=#
date_format=yyyy-MM-dd
time_format=HH:mm:Ss
datetime_format=yyyy-MM-dd HH:mm:Ss
web.xml
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>Filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- zh-cn encoding -->
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ActionContextCleanUp
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>JspSupportServlet</servlet-name>
<servlet-class>
org.apache.struts2.views.JspSupportServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
tomcat的配置
<Connector connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="GBK"/>
[最优解释]我给你说两点:
1、struts 2.x 中,Filter的执行顺序一般而言跟web.xml中配置的filter-mapping顺序有关。
你看看这篇文章,然后自己debug启动自己的服务,debug自己跟一遍,就会明白了这个filter的顺序,编码的变化。
http://www.gdcjxybbs.com/thread-1574-1-1.html
[其他解释]
用post方式呢?
[其他解释]
你是说提交action的时候? 默认就是post
[其他解释]
URIEncoding="UTF-8"/
在提交数据给前台的时候在后台打印一下提交的数据 看是否也是乱码
[其他解释]
tomcat的配置也修改为utf-8。
[其他解释]
tomcat改成utf-8的方式我都试过了,也是不行
写个了转码的过滤器,在过滤器哪里打印request.getparameter("username"),结果是????
后来在网上看别人说似乎request.getparameter也是有编码格式的,哎,太乱了。。。
都不知道怎么检查具体是在哪一步出错的
[其他解释]
还有一个说法是版本问题
2.1.6的版本会有中文乱码的问题,原因的话可以参考这个帖子,http://struts2.group.iteye.com/group/topic/11840?page=2
但是我看了下我下载最新版本,该问题已经解决了
[其他解释]
你既然看了那个帖子,就应该明白。
Struts2.0的乱码并不是使用过滤器进行处理的,而是要在struts.properties文件中加入以下配置:
struts.i18n.encoding=GBK
struts.properties要放在src目录下,这样可以解决参数传递中出现的乱码问题,这里的乱码处理是由Struts2.0的拦截器处理的,自己编写的过滤器处理时不会生效。
[其他解释]
问个基础问题,如果想正确显示中文,是应该用gbk还是utf-8?
[其他解释]把struts.properties中的encoding改成gbk,然后把自己加的2个过滤器删掉就好了
一个是
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>Filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
另一个是
<!-- zh-cn encoding -->
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ActionContextCleanUp
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
试着只去掉其中任意一个,结果都是会乱码,看来还是会起作用的。只是起了反作用
请教下iis姑娘 这是什么原因?
顺序是不是先tomcat的utf-8,然后是自己写的过滤器又设置了一次utf-8,接着就是struts自己转成了gbk
那么现在只是少了其中重复的一步,结果为什么就不一样了呢?
[其他解释]
其实你debug跟进去可以看到,request和response的编码,经过struts2的action的时候,编码统一被设置为了struts2配置文件中的编码。过滤器设置的编码被覆盖了,失去了作用。当然,只是对于进入struts的action的请求相应而言。
过滤器还是要要的。
如果你集成spring,就用spring自带的过滤器即可。
org.apache.struts2.dispatcher.ActionContextCleanUp这个你可以查一下相关资料,看看这个具体设置的何时起作用。
[其他解释]嗯,我奇怪的就是这点,既然过滤器设置的编码最终会被struts的配置覆盖掉,那么我加上去和不加应该没啥影响才对。。。但现在是加上自定义的过滤器之后就会乱码,去掉就好了。它影响地是哪一步?
ActionContextClearUp刚去查了下资料,明白是干嘛的了,刚试了下,加上去也不会出现乱码。
[其他解释]你把你自己过滤器放在
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这个后面试试看。
[其他解释]放后面就没事
这个是不是说明哪个先设置哪个起作用?
[其他解释]这个是过滤器的先后执行顺序。
[其他解释]说下我的理解:
过滤器在接受请求的时候是一个顺序,结果返回的时候则是前面顺序的倒序?
比如我把自定义的过滤器放前面,这样的话就该是这样的顺序
请求->UTF-8->GBK 结果->GBK-UTF8 所以乱码了?
如果把自定义的过滤器放后面,就是下面的顺序
请求->GBK->UTF8 结果->UTF8->GBK 所以就正常了?
[其他解释]
1、不知道EncodingFilter這個你是如何寫的。
2、struts2在2.1.3之前,
struts.i18n.encoding對于FilterDispatcher從源代碼看,只是對request的編碼做了過濾。response并沒有過濾,如果沒有額外自定義過濾器,則response時候,可能取決于view的編碼。
3、struts2 2.1.3之後,FilterDispatcher變成了StrutsPrepareAndExecuteFilter,你看看源代碼,是否跟FilterDispatcher一樣,只是對request過濾。
4、ActionContextCleanUp這個過濾器是struts2自身jar中的,你要看看源代碼,而且不知道你自定義的過濾器裏面是如何寫的。這倆要一個即可。
5、web.xml中,filter的執行順序當然也有關系。
[其他解释]是的。你再看看ActionContextCleanUp这个源码。
[其他解释]自己写的过滤器就是只对request设置了。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("自定义的Filter");
request.setCharacterEncoding("UTF-8");
System.out.println("request"+request.getParameter("username")+request.getParameter("password"));
chain.doFilter(request, response);
}
StrutsPrepareAndExecuteFilter的源码里面有一句,
prepare.setEncodingAndLocale(request, response);
似乎是对response也设置了。
我到现在还是没看懂为啥换了顺序就会结果不一样....
[其他解释]StrutsPrepareAndExecuteFilter中,配置的1i8n,也只是过滤request,没有对response做处理。
[其他解释]我现在已经不加ActionContextCleanUp了。虽然源码我也看过,不过没用它应该就不影响我了吧。。。
我的问题是
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
和
我自己写的Filter
为什么位置顺序不一样,结果就不一样(一个乱码,一个不乱吗)? 原因是什么?
是先执行的Filter会自动屏蔽掉后面的Filter,还是别的原因?
[其他解释]呃 其实能解决问题就差不多了
只是后面的讨论我感觉自己似乎理解力不够啊,每次你回答的我似乎都看不懂。。。。
我脑袋笨,能直接点回复我的问题么? 为什么顺序不一致,结果就不一样了?
[其他解释] Configuration freeMarkerCfg = new Configuration();
freemarker.template.Template template = null;
freeMarkerCfg.setClassForTemplateLoading(getClass(),"");
freeMarkerCfg.setObjectWrapper(new DefaultObjectWrapper());
freeMarkerCfg.setEncoding(getLocale(), "UTF-8");
// String reqFileName = "D:\\temp\\test.xml";
try {
template = freeMarkerCfg.getTemplate("testvm.txt");
Map<String, Object> parameters = new HashMap<String, Object>();
ValueObject val = new ValueObject();
val.setFname("妖要");
val.setGname("Yorker");
val.setEmail("test@mail.com");
val.setManager("manager");
parameters.put("p", val);
StringWriter sw = new StringWriter();
// OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(reqFileName), "UTF-8");
template.process(parameters, sw);
System.out.println(template);
getRequest().setAttribute("pts", sw);
sw.flush();
} catch (IOException e) {
// TODO
e.printStackTrace();
} catch (TemplateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return SUCCESS;
[其他解释]这帖先到这。。。。
我再重新开个帖子讨论。。。