在javaweb开发过程中数据在web层和servlet层交互的过程中经常会遇到中文乱码问题,针对这一情况现在提供如下几种方案:
1,在servlet层解决读取自浏览器的数据的时候的转码问题,解决的方法是HttpServletRequest的对象request中使用request.setCharacterEncoding(charset);方法,这个基本可以解决web层传回servlet层数据时的乱码问题,当然utf-8格式是具有一般适应性的一种编码格式,所以这里就以utf-8格式为例进行操作。言归正传,其操作方法是在接收数据的时候直接转码:
request.setCharacterEncoding("utf-8");
2,同样是在servlet层解决写出到浏览器时的转码问题,在跳转到浏览器地址之前使用HttpServletResponse的对象respose中使用response.setContentType(string);设置编码格式 进行操作,其操作方法还是以代码形式呈现一下:
response.setContentType("text/html;charset=utf-8");
3,使用一个过滤器Filter来解决乱码问题,这个可以为后面的一大堆servlet同时解决乱码问题,所以还是比较实用的,另外,这里还需要设置这个过滤器的控制范围,修改web.xml文件,设置其作用范围为整个项目,其代码实现方式为:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
/**
* 统一编码
* @author Administrator
*
*/
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//1.强转
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
request.setCharacterEncoding("utf-8");
//2.放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
private boolean flag=true;
public MyRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override
public String getParameter(String name) {
if(name==null || name.trim().length()==0){
return null;
}
String[] values = getParameterValues(name);
if(values==null || values.length==0){
return null;
}
return values[0];
}
@Override
/**
* hobby=[eat,drink]
*/
public String[] getParameterValues(String name) {
if(name==null || name.trim().length()==0){
return null;
}
Map<String, String[]> map = getParameterMap();
if(map==null || map.size()==0){
return null;
}
return map.get(name);
}
@Override
/**
* map{ username=[tom],password=[123],hobby=[eat,drink]}
*/
public Map<String,String[]> getParameterMap() {
/**
* 首先判断请求方式
* 若为post request.setchar...(utf-8)
* 若为get 将map中的值遍历编码就可以了
*/
String method = request.getMethod();
if("post".equalsIgnoreCase(method)){
try {
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if("get".equalsIgnoreCase(method)){
Map<String,String[]> map = request.getParameterMap();
if(flag){
for (String key:map.keySet()) {
String[] arr = map.get(key);
//继续遍历数组
for(int i=0;i<arr.length;i++){
//编码
try {
arr[i]=new String(arr[i].getBytes("iso8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
flag=false;
}
//需要遍历map 修改value的每一个数据的编码
return map;
}
return super.getParameterMap();
}
}
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>
4,前面几种方式是比较常用的方法,至少在我目前学习中是这样的,还有一种比较极端的方法,那就是修改服务器的配置文件,配置tomcat如下位置添加一句代码:URIEncoding="UTF-8",其位置如下截取的部分代码,就是设置端口的位置,添上基本上也可以解决:
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define a SSL HTTP/1.1 Connector on port 8443
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
另外,是否还有其他方法我并没有掌握,如果有小伙伴路过看到,希望能多多指点一下!