博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sitemesh2.x+velocity+springmvc乱码解决方案
阅读量:5049 次
发布时间:2019-06-12

本文共 4605 字,大约阅读时间需要 15 分钟。

sitemesh2.x+velocity乱码解决方案.md

引言

通常我们在采用springmvc+velocity架构的时候只需要跳转到action然后在转回html页面,此时即可通过velocity的固有语法在html中取出各种变量。当当我们想在以上的架构中加入sitemesh2.x 的时候会发现配置装饰页面时采用action会出现一些错误,而只能直接使用.vm来配置装饰器页面,可是这样直接跳转的做法很多时候会出现一些乱码问题。

正文

有人会说,可以在velocity的配置文件中加入字符集设置,配置如下:

1 input.encoding = UTF-82  output.encoding = UTF-83 response.setContentType("text/html;charset=utf-8");    4 request.setContentType("text/html;charset=utf-8");

 

然后再在spring配置velocity试图解析器的时候加入如下代码,其中<property name="contentType" value="text/html;charset=utf-8" />约定了编码格式为utf-8

1 
2
4
5
6
7
8
9
10
11 12
13
14
15
16
19

 

我相信以上方法已经解决了部分人的乱码问题,但是这一类相关文章我也看了很多,我的问题依然没有解决。

其实上述方法无法解决问题的时候,还有一套终极手段,就是修改服务器的编码方式为utf-8,这种方案通常可以解决绝大部分的乱码问题。但是,这种方法不到万不得已的时候不能使用,因为很有可能公用服务器的时候,你根本没有权限甚至你根本就不能去修改服务器的编码方式,因为这很可能对公用服务器造成一系列未知问题。
我出现的乱码情况比较奇异,因为我访问的内容页是 localhost:8080/sourceDemo/index.action ,而按照sitemesh的组合后的页面的规则来看实际应该就是 访问test.vm这个文件,在这个文件中我有如下变量声明:

其中${body} 是取得用户访问的页面的body标签内的所有元素,而我得到的结果是

哈利路亚四个字乱码了,也就是说装饰器页面乱码,而用户访问的页面没有乱码。
然后通过velocity解析成html页面
于是乎,出于上述考虑,我便决定查看sitemesh源码。
以下先给出我的sitemesh在配置文件中的相应配置:
web.xml中的配置:

1 
2
3
sitemesh
4
com.opensymphony.module.sitemesh.filter.PageFilter
5
6
7
sitemesh
8
/*
9
10
11 12
13
14
site-mesh-velocity
15
com.cloudwinker.source.sitemesh.module.velocity.VelocityDecoratorServlet
16
1
17
18 19
20
site-mesh-velocity
21
*.vm
22
23

 

sitemesh.xml中的配置

 

decorator.xml中的配置

/views/admin/*

 

其中根目录下得test.vm即为装饰器页面,我将用它来装饰内容页

sitemesh是通过filter来实现的,因此入口其实就是filter部分,
而我配置在web.xml的filter中的部分,实际上是一个与velocity结合的工具,其原本的配置并非是这个,而是com.opensymphony.module.sitemesh.velocity.VelocityDecoratorServlet

site-mesh-velocity
com.cloudwinker.source.sitemesh.module.velocity.VelocityDecoratorServlet
1
site-mesh-velocity
*.vm

 

我使用jd-gui工具反编译了sitemesh的源码,发现他实际上继承了org.apache.velocity.tools.view.servlet.VelocityViewServlet;也就是velocity-tools-2.0的jar包,目的就在于将sitemesh出来的页面整合到vm文件中去

这是我修改后的VelocityDecoratorServlet

该文件是直接copysitemeshjar包种的org.apache.velocity.tools.view.servlet.VelocityViewServlet 内容,其中最后一句发现

getTemplate(template)实际上是取得velocity的api中的velocity的一个方法,我从debug中得到最后return velocityTemplate时,该对象的encoding属性为ISO-8859-1 ,因为这个原因导致最终显示在页面时,原本属于test.vm的数据全部显示乱码!因此后续的内容就变更为改变在省城velocity模板之前,改变文件的encoding属性!

于是我通过debug追踪,找到了这个文件,也就是velocity-tool-2.0jar包中的 org.apache.velocity.tools.view.velocityView.java这个文件,我截取部分源码给大家看一下:

这就是最后实际调用的方法,从方法内部发现,当encoding==null时实际上使用的是默认的编码方式。我在debug时发现代码运行的这一句的时候,实际encoding的值是null。
因此无论我们在velocity文件中如何配置,都只能得到ISO-8859-1的编码格式文件,于是中文乱码就成了必然情况。
知道了原因后,剩下的就是修改代码了。之所以这里的encoding是null,我想很有可能跟springmvc+velocity 的配置时,实际上使用的spring的响应机制,因此直接从actiong访问时所有编码正常,而直接sitemesh将vm作为装饰器文件时却出现乱码情况,因为sitemesh只是简单的在web.xml中配置了filter,并没有与spring做相应整合。
于是理论上解决方案有两种:其中一种就是改写sitemesh的filter,使之能够在spring的机制中使用,这样的话就能透过spring来取得velocity的相关编码的配置了。由于我太懒了,目前懒得用这种方式去改写,因为嫌他太麻烦。
第二种方式:实际上就是重写org.apache.velocity.tools.view.velocityView.java 这个文件,将getTemplate这个方法改写成如下
之后重启服务器,运行,问题解决!

 

转载于:https://www.cnblogs.com/andrewlee/p/3825653.html

你可能感兴趣的文章
java程序员常见面试题
查看>>
java @SuppressWarnings注解
查看>>
关于插件的开发入门。
查看>>
JS控制文本框只能输入数字 \保留小数点后两位
查看>>
php开启opcache
查看>>
C语言位域
查看>>
Python量化教程 常用函数
查看>>
webpack笔记一 起步
查看>>
使用Mdbg.exe 调试.Net 程序
查看>>
谈开发框架
查看>>
Csharp--Read Csv file to DataTable
查看>>
通过 CLI 管理 Jenkins Server
查看>>
使用json格式的数据进行通信
查看>>
php为图片添加水印
查看>>
Datagrid扩展方法InitEditGrid{支持单元格编辑}
查看>>
Numpy学习50例
查看>>
import renumber.py in pymol
查看>>
ionic ngcordova map 地圖
查看>>
对方法继承的深入学习
查看>>
几个机器学习上的概念
查看>>