阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Tomcat部署在CentOS 6.8上乱码问题解决

87次阅读
没有评论

共计 5480 个字符,预计需要花费 14 分钟才能阅读完成。

web 访问经常会莫名其妙的出现各种乱码问题。按照我自己的理解,设置一个 charSet 的过滤器,代码如下:import java.io.IOException;

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 java.io.ByteArrayOutputStream; 
import java.io.OutputStreamWriter; 

public class Charset implements Filter {

    @Override// 过滤器销毁
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override//chain 我感觉是对 request 的一次转发
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // 设置字符编码,解决乱码问题
        request.setCharacterEncoding(“utf-8”);
        response.setCharacterEncoding(“utf-8”);
        response.setContentType(“chatset=utf-8”);

        chain.doFilter(request, response);// 让目标执行,放行

    }

    @Override// 过滤器初始化
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }
   
      private static String getDefaultCharSet() { 
            OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream()); 
            String enc = writer.getEncoding(); 
            return enc; 
        } 

}

然后在 tomcat 的 conf 目录下 server.xml 添加那么一句  URIEncoding=”UTF-8″

<Connector port=”8080″ protocol=”HTTP/1.1″

              connectionTimeout=”20000″

              redirectPort=”8443″  URIEncoding=”UTF-8″  />

最后记得每个 jsp 的开头都要记得  pageEncoding=”utf-8″

<%@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″%>

基本上 javaWeb 的开发就不会出现什么乱码问题了。

然后想得深入些,String 类里面有个方法  String.getBytes(),这个方法 JDK 的源码是这样子的

@Deprecated
    public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd – srcBegin);
        }
        int j = dstBegin;
        int n = srcEnd;
        int i = srcBegin;
        char[] val = value;  /* avoid getfield opcode */

        while (i < n) {
            dst[j++] = (byte)val[i++];
        }
    }

    /**
    * Encodes this {@code String} into a sequence of bytes using the named
    * charset, storing the result into a new byte array.
    *
    * <p> The behavior of this method when this string cannot be encoded in
    * the given charset is unspecified.  The {@link
    * java.nio.charset.CharsetEncoder} class should be used when more control
    * over the encoding process is required.
    *
    * @param  charsetName
    *        The name of a supported {@linkplain java.nio.charset.Charset
    *        charset}
    *
    * @return  The resultant byte array
    *
    * @throws  UnsupportedEncodingException
    *          If the named charset is not supported
    *
    * @since  JDK1.1
    */
    public byte[] getBytes(String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null) throw new NullPointerException();
        return StringCoding.encode(charsetName, value, 0, value.length);
    }

    /**
    * Encodes this {@code String} into a sequence of bytes using the given
    * {@linkplain java.nio.charset.Charset charset}, storing the result into a
    * new byte array.
    *
    * <p> This method always replaces malformed-input and unmappable-character
    * sequences with this charset’s default replacement byte array.  The
    * {@link java.nio.charset.CharsetEncoder} class should be used when more
    * control over the encoding process is required.
    *
    * @param  charset
    *        The {@linkplain java.nio.charset.Charset} to be used to encode
    *        the {@code String}
    *
    * @return  The resultant byte array
    *
    * @since  1.6
    */
    public byte[] getBytes(Charset charset) {
        if (charset == null) throw new NullPointerException();
        return StringCoding.encode(charset, value, 0, value.length);
    }

    /**
    * Encodes this {@code String} into a sequence of bytes using the
    * platform’s default charset, storing the result into a new byte array.
    *
    * <p> The behavior of this method when this string cannot be encoded in
    * the default charset is unspecified.  The {@link
    * java.nio.charset.CharsetEncoder} class should be used when more control
    * over the encoding process is required.
    *
    * @return  The resultant byte array
    *
    * @since      JDK1.1
    */
    public byte[] getBytes() {
        return StringCoding.encode(value, 0, value.length);
    }

如果不指定 String.getBytes()里面的参数,它会调用系统默认的参数,也就是 java 虚拟机的默认参数,查看这个参数的方法如下所示

  System.out.println(“Default Charset=” + java.nio.charset.Charset.defaultCharset()); 
  System.out.println(“file.encoding=” + System.getProperty(“file.encoding”)); 
  System.out.println(“Default Charset=” + java.nio.charset.Charset.defaultCharset()); 
  System.out.println(“Default Charset in Use=” + getDefaultCharSet()); 

值得一提的是,当你使用 sftp 工具上传文件至服务器时,如果没有指定 sftp 协议的文件名格式,sftp 工具会以你默认系统的编码(大部分 windows 的编码都是 GBK)传送中文文件名给服务器,这时候如果服务器默认的编码方式不是 GBK,那么你上传的文件名在服务器端显示都是乱码。

CentOS 查看系统的编码方式的命令是  echo $LAN,也可以输入 locale  命令查看系统的编码。

在 tomcat7 中,用 get 方式访问中文名的文件,如 uploads/%E6%B5%8B%E8%AF%95.mp3

浏览器本身会借助 url.enCode()把中文名,空格等等转化为 %E8 等等的 web 地址传输编码格式,然后 servlet 接收到这个地址后会先 url.unCode 换成普通的编码,然后再根据 request.setContentType=”UTF-8″ 来换成中文名,但是这样子设置 tomcat 的 URIEncoding=”UTF-8″ 又是闹得哪样?

更多 Tomcat 相关教程见以下内容

CentOS 6.6 下安装配置 Tomcat 环境  http://www.linuxidc.com/Linux/2015-08/122234.htm

RedHat Linux 5.5 安装 JDK+Tomcat 并部署 Java 项目  http://www.linuxidc.com/Linux/2015-02/113528.htm 

Tomcat 权威指南(第二版)(中英高清 PDF 版 + 带书签)  http://www.linuxidc.com/Linux/2015-02/113062.htm 

Tomcat 安全配置与性能优化 http://www.linuxidc.com/Linux/2015-02/113060.htm 

Linux 下使用 Xshell 查看 Tomcat 实时日志中文乱码解决方案 http://www.linuxidc.com/Linux/2015-01/112395.htm 

CentOS 64-bit 下安装 JDK 和 Tomcat 并设置 Tomcat 开机启动操作步骤 http://www.linuxidc.com/Linux/2015-01/111485.htm 

Ubuntu 16.04 下安装 Tomcat 8.5.9  http://www.linuxidc.com/Linux/2017-06/144809.htm

Tomcat 中 session 的管理机制  http://www.linuxidc.com/Linux/2016-09/135072.htm

Tomcat 的详细介绍:请点这里
Tomcat 的下载地址:请点这里

更多 CentOS 相关信息见CentOS 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=14

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-09/146733.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计5480字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中