浏览器页面传值到服务器端中文乱码问题

本文探讨了在Java Web应用中遇到的中文乱码问题,特别是GET和POST请求时的处理方式。对于POST请求,通过设置request.setCharacterEncoding("utf-8")可在最开始解决乱码。而在GET请求时,需要将ISO-8859-1编码的数据转换为UTF-8。为避免每个Servlet重复处理,建议在Filter中采用装饰者模式统一处理,装饰者需与被装饰者实现相同接口,增强获取参数的方法,并保留原有行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

在整个网站中,可能会有get请求或post请求向服务器提交参数.参数中往往有中文信息.在后台每个Servlet中都需要去处理乱码.为了不用每个servlet都处理中文乱码,我们可以在filter中处理乱码问题。

分析:

首先请求的方式不同,处理的方式也不同:

  1. post请求:如果是post请求,只需调用request.setCharacterEncoding("utf-8");即可解决(注意这句话一定要在最前面调用)。
  2. get请求:如果是get请求,这种方式较为麻烦一点,以get传送数据的话会把数据编码会转换为iso-8859-1编码,所以在servlet接收到数据之后,需要转换成正确的编码,可以使用类似的方法解决:new String(value.getBytes("iso8859-1"),"utf-8");

要在filter中解决乱码问题,可以在filter中对request的获取参数的一系列方法进行加强,一般使用装饰着模式:

装饰者书写步骤:

  1. 要求装饰者和被装饰者实现同一个接口或者继承同一个类
  2. 装饰者中要有被装饰者的引用
  3. 对需要加强方法进行加强
  4. 对不需要加强的方法调用原来的方法即可
加强request的方法后再传给filter的放行方法chain.doFilter(new MyRequest(request), response);
最后在web.xml文件中配置自定义的filter即可:
<filter>
  <filter-name>EncodingFilter</filter-name>
  <filter-class>xxx.web.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>EncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
以下是自定义的filter:
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;
		
		//2.放行,放入加强后的request
		chain.doFilter(new MyRequest(request), response);
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}
}
// 使用装饰着模式加强request的方法
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();
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值