客户端向服务器提交数据的时候,一般提交方式是“GET”和“POST”提交方式,当然还有其他提交方式。
以下讨论以客户端jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
即jsp客户端页面使用UTF-8方式编码。
问题的出现:
一、以POST方式提交数据的时候,使用request.setCharacterEncoding(“UTF-8”)即可将从客户端提交上来的数据用客户端的Encoding方式编码。这样在控制台响应的编码就不会出现乱码。
二、以GET方式提交数据的时候,请求参数在请求行中,而request.setCharacterEncoding("UTF-8")只能改变实体内容中的编码方式,不能改变请求行中的内容。
所以我们没有能够改变编码的方式。需要手动
if("POST".equals(method)){
request.setCharacterEncoding("UTF-8");
String regName1 = request.getParameter("name");
String pwd1 = request.getParameter("jiguan");
System.out.println("姓名:"+regName1+"籍贯"+pwd1);
}
但是
1、需要每次都写上如上的代码;2、编码不同,需要慢慢修改。
问题的探讨:
一、将每次从客户端提交上来的数据经过编码处理后交给客户端或者控制台,但是request没有set方法,此法不行。
二、在获取得到客户端的数据的时候即将编码问题统一化。直接会在服务器端得到一个已经转换完备的编码。
为了完成这样的操作,我们需要改造request.getParameter(),request.getParameterValues(),request.getParameterMap()这三个方法。
/********************************************************************/
改造方法的方法。
1、继承以重写方法;
2、装饰类;
3、动态代理;
问题的解决:
我们使用继承这样的方法去重新改造以上三种get方法。
http中提供了一个类javax.servlet.http.HttpServletRequestWrapper;
All Implemented Interfaces:
HttpServletRequest, ServletRequest
表明HttpServletRequest和ServletRequest均是实现了该类的接口。这样我们就可以继承这个类去改写request中的三个get方法。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/**
* 这是一个解决全站乱码的Filter
*/
/**
* 涉及到request的操作,且必须用request去获取操作对象,所以我们要改造request中的get
*/
/**
* String getParameter(String name)
Returns the value of a request parameter as a String, or null if the parameter does not exist.
Map getParameterMap()
Returns a java.util.Map of the parameters of this request.
Enumeration getParameterNames()
Returns an Enumeration of String objects containing the names of the parameters contained in this request.
String[] getParameterValues(String name)
Returns an array of String objects containing all of the values the given request parameter has, or null if the parameter does not exist.
*/
/**
* 且以上方法除了Enumeration getParameterNames() 该方法不需要重写外,均需要重写。
*/
/**
* 为此,我们需要重新定义一个MyRequest这样的类似的东西。
*/
/**
* 提供了这样的接口
*/
//先用一行代码直接将响应编码设置
response.setContentType("text/html;charset=UTF-8");
HttpServletRequest request1 = (HttpServletRequest) request;
chain.doFilter(new MyHttpServletRequest(request1), response);
}
class MyHttpServletRequest extends HttpServletRequestWrapper
{
private HttpServletRequest request;
private boolean hasNotEncode = true;
//构造方法
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
// TODO Auto-generated constructor stub
this.request = request;
}
//重写方法
@Override
public Map<String, String[]> getParameterMap() {
// TODO Auto-generated method stub
/**
* 将最为复杂的方法严格书写,其他的两个方法均可以使用实现了的该方法简介调用
*/
//判断是何种提交方式
String method = request.getMethod();
if("POST".equals(method)){
//如果是POST提交方式,那么就直接一行代码解决
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return request.getParameterMap();
}else if("GET".equals(method)){
//如果是GET方式提交
//获得请求体中的提交参数
Map<String, String[]> map = request.getParameterMap();
//此处不能使用增强for循环,因为增强for循环不能在循环体中做修改这样的动作
if(hasNotEncode){
Set<Entry<String, String[]>> set = map.entrySet();
Iterator<Entry<String, String[]>> it = set.iterator();
while(it.hasNext())
{
Entry<String, String[]> en = it.next();
String[] values = en.getValue();
//循环该values String类型的数组,并改变编码
for (int i = 0; i < values.length; i++) {
try {
values[i] = new String(values[i].getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
hasNotEncode=false;
}
return map;
//改变编码
}else{
//除此两种方式的其他提交方式,就直接返回
return request.getParameterMap();
}
}
@Override
public String[] getParameterValues(String name) {
// TODO Auto-generated method stub
return getParameterMap().get(name);
}
@Override
public String getParameter(String name) {
// TODO Auto-generated method stub
String[] str = getParameterValues(name);
return str==null?null:str[0];
}
}
其中编码改变了之后的解决方法:
将编码这个东西参数话即可。
public void init(FilterConfig filterConfig) throws ServletException {
String encode = filterConfig.getInitParameter("encode");
this.encode = encode == null ? "utf-8" : encode;
}
并且在web.xmlwen文件中做出init-param的配置。