解决web工程中文乱码几种方式

本文介绍了三种解决web工程中文乱码的方法:原始编码转换,动态代理编码过滤和装饰者模式编码过滤。原始方法需要在每个Servlet上手动转化,较为麻烦。动态代理编码过滤通过过滤器实现统一处理,而装饰者模式则更方便地解决了GET请求的编码问题。

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

第一种:原始编码转换

  • 在get请求中,每次获取参数,都使用下列方式转化
    • new String(name.getBytes(“ISO-8859-1”), “UTF-8”);
  • post方式在获取参数前转化编码格式即可
    • req.setCharacterEncoding(“UTF-8”);
  • 缺点:需要在每个Servlet上每次请求都需要转化处理,太过麻烦,推荐使用第二种或第三种
代码
   @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        String name = req.getParameter("name");
        name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
        System.out.println("Get name:" + name);
    }

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        req.setCharacterEncoding("UTF-8");
        String name = req.getParameter("name");
        System.out.println("Post name:" + name);
    }

第二种:动态代理编码过滤

过滤器代码
/**
 * 使用动态代理进行编码过滤
 */
public class EncodingFilter implements Filter
{

    @Override
    public void destroy()
    {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException
    {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                req.getClass().getInterfaces(), new InvocationHandler()
                {

                    Object obj = null;

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
                    {
                        // 只针对获取参数方法
                        if ("getParameter".equals(method.getName()))
                        {
                            // 判断get和post提交方式
                            String m = request.getMethod();
                            if ("GET".equals(m))
                            {
                                // 原本方法得出的参数

                                String value = (String) method.invoke(req, args);
                                value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
                                return value;
                            } else
                            {
                                // 其他提交方式
                                req.setCharacterEncoding("UTF-8");
                                obj = method.invoke(req, args);
                            }
                        } else
                        {
                            obj = method.invoke(req, args);
                        }

                        return obj;
                    }
                });
        chain.doFilter(proxy, resp);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException
    {
    }
}

web.xml配置
<filter>
  	<filter-name>EncodingFilter</filter-name>
  	<filter-class>com.zgd.learn.servlet.demo.EncodingFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>EncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

第三种:装饰着模式编码过滤

  • 除get请求,一般都只需要在获取请求参数前添加下列代码即可
    • request.setCharacterEncoding(“UTF-8”);
  • get请求,为避免每次请求都手动转化参数太过麻烦,可以使用装饰者模式,修改ServletRequest请求
过滤器代码
/**
 * 过滤所有请求,将请求和响应的编码格式统一转化为UTF8 将响应编码格式
 */
public class EncodingFilter implements Filter
{

    @Override
    public void destroy()
    {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException
    {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String method = httpRequest.getMethod();
        // 设置响应编码格式
        response.setContentType("text/html;charset=utf-8");
        if ("GET".equals(method))
        {
            // 因为不知道具体哪个请求参数需要转换编码格式,所以使用装饰类进行处理
            EncodingServletRequest encodingServletRequest = new EncodingServletRequest(httpRequest);
            chain.doFilter(encodingServletRequest, response);
        } else if ("POST".equals(method))
        {
            request.setCharacterEncoding("UTF-8");
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
    }

}

装饰者EncodingServletRequest
public class EncodingServletRequest extends HttpServletRequestWrapper
{
    private HttpServletRequest request;

    public EncodingServletRequest(HttpServletRequest request)
    {
        super(request);
        this.request = request;
    }

    @Override
    public String getParameter(String name)
    {
        String value = request.getParameter(name);
        try
        {
            return new String(value.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
            throw new RuntimeException("Encoding is not ISO-8859-1");
        }
    }

}

web.xml配置
<filter>
  	<filter-name>EncodingFilter</filter-name>
  	<filter-class>com.zgd.learn.servlet.demo.EncodingFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>EncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值