弃成见,反省,并重新认识struts.i18n.encoding

简介:
[size=medium]之前和大家讨论了struts2.0中struts.i18n.encoding参数的作用,但是由于自己的不严谨的态度使自己得出了片面得结论,在此表示道歉.当然我们程序员的目的只有一个,就是寻找真相.所以下面我会和大家一起来重新理解struts.i18n.encoding参数的含义.

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

首先有三个返回类型:
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <constant name="struts.devMode" value="false" />
<constant name="struts.i18n.encoding" value="UTF-8" />
<constant name="struts.velocity.manager.classname" value="demo.DemoVelocityManager"/>

<package name="/" namespace="/" extends="struts-default">
		
		<action name="test" class="demo.HelloWorldAction">
			<result name="jsp">helloworld.jsp</result>
			<result name="velocity" type="velocity">helloworld.vm</result>
			<result name="freemarker" type="freemarker">helloworld.ftl</result>
		</action>
	</package>


接着定义action:
访问:
http://localhost:8080/demo/test!jsp.action

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


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

看上去返回流的编码没有变化,都是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.如下:

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

然后分别请求

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

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

http://localhost:8080/demo/test!velocity.action
由此可见在freemarker和velocity中struts.i18n.encoding确实被用来作为response返回流中content-type的charset值.

那么为什么jsp不是这样的呢.
因为jsp并不是模板,而是一个类,在真正运行的时候,servlet容器会把jsp编译成一个类.我们的HelloWorld.jsp就变成了HelloWorld_jsp.java,在这个类中我们可以看到如下代码:
修改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水平有限,很有可能还是没有挖掘出更深层次的见解,希望您能多指正.
[/size]  
目录
相关文章
|
5月前
|
开发框架 小程序 前端开发
带你了解小程序的框架之谜
带你了解小程序的框架之谜
|
1月前
|
移动开发 安全 前端开发
代码混淆不再愁:一篇掌握核心技巧
代码混淆不再愁:一篇掌握核心技巧
22 5
|
4月前
|
XML Java 关系型数据库
框架前奏
框架前奏
35 1
|
11月前
|
SQL XML 存储
MyBatis这样用,同事直呼哇塞,堪称最佳实践
MyBatis是一款非常流行的ORM框架,相信很多小伙伴都在使用。我们经常会把它和MyBatis-Plus或者MBG一起使用,用多了之后对于其一些常规操作就不太熟悉了。最近总结了下MyBatis的实用用法和技巧,希望对大家有所帮助!
|
11月前
|
JSON 前端开发 Java
JavaWeb编年史(远古时期)
JavaWeb编年史(远古时期)
156 0
|
SQL JavaScript 前端开发
#你会担心掌握的技术语言过时吗?#一入编程深似海,从此妹子是路人
我掌握的技术语言有C、C++、ActionScript、JavaScript、TypeScript、Flex、Java、SQL、Scala、CAD,当然,这还不算一些具有特殊语言的技术框架,如Vue.js、Angular、Spark、Android、HarmonyOS、Node.js等,如果算上就更多了。
211 0
|
存储 缓存 JavaScript
想好怎么学 Servlet规范了嘛?想好了嘛?没想好先看看这篇文章(爆肝之作),先看着然后慢慢想!!
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
想好怎么学 Servlet规范了嘛?想好了嘛?没想好先看看这篇文章(爆肝之作),先看着然后慢慢想!!
|
存储 Python
用“讲故事”的方式,带你认识Python编码问题起源和发展!(二)
用“讲故事”的方式,带你认识Python编码问题起源和发展!(二)
用“讲故事”的方式,带你认识Python编码问题起源和发展!(二)
|
存储 Python
用“讲故事”的方式,带你认识Python编码问题起源和发展!(一)
用“讲故事”的方式,带你认识Python编码问题起源和发展!(一)
用“讲故事”的方式,带你认识Python编码问题起源和发展!(一)
|
XML 存储 Java
【XML入门】一篇文章让你从没听过到熟练运用
今天我们继续来学习【Java Web】部分的XML,XML相比其他部分来时还是非常简单的。我们在以后写大项目时候也会经常用到,所以说还是蛮重要的。
【XML入门】一篇文章让你从没听过到熟练运用

热门文章

最新文章