SpringMVC-15-乱码问题处理

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 SpringMVC-15-乱码问题处理,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

8.乱码问题

8.1 ServletAPI方式

  • 乱码出现在HTTP请求方式是POST;Get不乱码,但是地址栏会暴露传递的数据,
  • 回顾之前servlet Web解决乱码问题时:要么在servlet方法里面加乱码设置
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        String username = req.getParameter("username");
        }
}
  • 要么加自定义过滤器之后在web.xml中注册,这两种方式都可以解决
public class SysFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {

    }
}

web.xml中如果还有其他过滤器。编码过滤器filter一定要放在web.xml的第一个,不然还是会乱码

拦截路径要用/*不然不会拦截jsp,了解下tomcat的默认JspServlet配置映射路径

<filter>
    <filter-name>SysFilter</filter-name>
    <filter-class>com.zk.myfilter.SysFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SysFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8.2 springmvc乱码处理

  • springmvc这块乱码的原因是controller的方法参数已经经接收流并编码了后面再编码就没用了,所以只能外加编码过滤器
  • 可以用自定义过滤器可以处理

自定义过滤器思想:对post方式提交的数据直接使用utf-8编码;对get方式提交的数据是将字符以ISO-8859-1解码为二进制流,再以UTF-8编码为字符

  • 可以用springmvc自带的编码过滤器,直接在web.xml中注册即可
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这个过滤器在某些情况下对get支持不好

  • 乱码情况也要注意下tomcat配置文件中编码设置!
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               redirectPort="8443"  URIEncoding="utf-8"  executor="tomcatThreadPool"/>

8.3 Spring Json乱码

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/gj01")
    @ResponseBody
    public String getjson01(){
        User user = new User("张三", 18, LocalDate.now());
        return user.toString();
    }
}
  • http://localhost:8080/user/gj01地址栏直接访问出现乱码
    在这里插入图片描述

  • 返回string,则使用 StringHttpMessageConverter,而这个convert使用的是字符集是iso-8859-1,而且是final的。所以在当返回json中有中文时会出现乱码。

@ResponseBody作用是将标注该注解的处理方法的返回结果直接写入 HTTP Response Body**(Response 对象的 body 数据区)中。一般情况下,@ResponseBody 都会在异步获取数据时使用**,被其标注的处理方法返回的数据都将输出到响应流中,客户端获取并显示数据。

  • StringHttpMessageConverter在写入输出消息时,它还增加了对Content-Type和Content-Length的支持。

  • 解决方式1:

  • produces 属性用于指定返回的内容类型,返回的内容类型必须是 request 请求头(Accept)中所包含的类型。还可以指定返回值的编码
解决方式1@RequestMapping(value = "toUser",produces = "application/json;charset=UTF-8")。
  • 解决方式2:统一解决json乱码的方式不用每个方法上添加produces = “application/json;charset=utf-8″属性

  • 如果用Jackson 开源工具进行json格式处理时乱码解决:

在springmvc-servlet.xml配置文件中添加一段消息转换配置StringHttpMessageConverter

<!--json乱码问题统一配置-->
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <!--乱码问题解决-->
            <constructor-arg name="defaultCharset" value="UTF-8"/>
        </bean>
        <!--具体那种消息转换配置去实现-->
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                    <property name="failOnEmptyBeans" value="false"/>
                 </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
  • 如果用fastjson进行json格式处理时乱码解决:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <!--开启注解-->
    <context:component-scan base-package="com.zk"/>
    <!--让spring-mvc不处理静态资源.css .js-->
    <mvc:default-servlet-handler/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- annotation-driven用于简化开发的配置,注解DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    
    <!-- 使用resources过滤掉不需要dispatcherservlet的资源(即静态资源,例如css、js、html、images)。
        在使用resources时必须使用annotation-driven,否则resources元素会阻止任意控制器被调用 -->
    <!-- 允许js目录下的所有文件可见 -->
    <!--<mvc:resources mapping="/**" location="/"/>-->
    <!--json乱码问题统一配置-->
    
    <mvc:annotation-driven conversion-service="formattingConversionService">
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <!--乱码问题解决-->
                <constructor-arg name="defaultCharset" value="UTF-8"/>
            </bean>
            <bean class="com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter">
            </bean>
            <!--<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            </bean>-->
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--注册MyFormatter -->
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="formattingConversionService">
        <property name="formatters">
            <list>
                <bean class="com.zk.formatter.MyFormatter"/>
            </list>
        </property>
    </bean>
    <!--<bean id="fastJsonpResponseBodyAdvice"
          class="com.alibaba.fastjson2.support.spring.FastJsonpResponseBodyAdvice">
        <constructor-arg>
            <list>
                <value>callback</value>
                <value>jsonp</value>
            </list>
        </constructor-arg>
    </bean>-->
</beans>
  • 举例:利用ajax将json数据传到后台接收,后台在将json数据回显到页面展示

  • 实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    String username;
    String pwd;
    Date birthday;
}
  • controller
@Controller
@RequestMapping("/stu")
public class StudentController {
    @RequestMapping("/getInfo")
    @ResponseBody
    public Student getInfo(@RequestBody Student student){
        // 打印接收的 JSON数据
        System.out.println("接收的student数据:"+student.toString());
        return student;
    }

}

方法中的 @RequestBody 注解用于将前端请求体中的 JSON 格式数据绑定到形参 user 上,@ResponseBody 注解用于直接返回 Student对象(当返回 POJO 对象时默认转换为 JSON 格式数据进行响应)。

  • 参数日期格式化类
@Component
public class MyFormatter implements Formatter<Date> {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        return dateFormat.parse(text);
    }

    @Override
    public String print(Date object, Locale locale) {
        return dateFormat.format(object);
    }
}
  • springmvc-servlet.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <!--开启注解-->
    <context:component-scan base-package="com.zk"/>
    <!--让spring-mvc不处理静态资源.css .js-->
    <mvc:default-servlet-handler/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- annotation-driven用于简化开发的配置,注解DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    
    <!-- 使用resources过滤掉不需要dispatcherservlet的资源(即静态资源,例如css、js、html、images)。
        在使用resources时必须使用annotation-driven,否则resources元素会阻止任意控制器被调用 -->
    <!-- 允许js目录下的所有文件可见 -->
    <!--<mvc:resources mapping="/**" location="/"/>-->
    <!--json乱码问题统一配置-->
    
    <mvc:annotation-driven conversion-service="formattingConversionService">
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <!--乱码问题解决-->
                <constructor-arg name="defaultCharset" value="UTF-8"/>
            </bean>
            <bean class="com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter">
            </bean>
            <!--<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            </bean>-->
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--注册MyFormatter -->
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="formattingConversionService">
        <property name="formatters">
            <list>
                <bean class="com.zk.formatter.MyFormatter"/>
            </list>
        </property>
    </bean>
</beans>
  • index.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- 可选的Bootstrap主题文件(一般不使用) -->
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap-theme.min.css"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<html>
  <head>
    <title>testJSON发送和回显</title>
    <script type="text/javascript">
      $(function () {
          $("#add").click(function () {
            let username = $("#username").val();
            let pwd = $("#pwd").val();
            let birthday = $("#birthday").val();
            $.ajax({
                url:"${pageContext.request.contextPath}/stu/getInfo",
              //请求类型
              type:"post",
              //data表示发送的数据
              data : JSON.stringify({
                username : username,
                pwd : pwd,
                birthday:birthday
              }), //定义发送请求的数据格式为JSON字符串
              contentType : "application/json;charset=utf-8",
              //定义回调响应的数据格式为JSON字符串,该属性可以省略
              dataType : "json",
              //成功响应的结果
              success:function (data) {
                let html = "";
                if (data != null) {
                    html+= "<tr><td class='info'>"+data.username+"</td><td class='info'>"+data.pwd+"</td><td class='info'>"+data.birthday+"</td></tr>"
                }
                alert(html);
                $("#content").html(html);
              }
            })
          })
      })
    </script>
  </head>
  <body>
    <div class="container">
      <div class="row clearfix">
        <div class="col-md-12 column">
          <div class="page-header">
            <small>学生账号信息JSON发送和回显</small>
          </div>
        </div>
      </div>
      <form method="post" action="#">
        <div class="form-group">
          <label for="username">学生账号</label>
          <input type="text" class="form-control" id="username" name="username" placeholder="学生姓名" required>
        </div>
        <div class="form-group">
          <label for="pwd">密码</label>
          <input type="text" class="form-control" id="pwd" name="pwd" placeholder="密码" required>
        </div>
        <div class="form-group">
          <label for="birthday">登录日期</label>
          <input type="datetime-local" name="birthday" id="birthday" class="form-control" placeholder="登录日期">
        </div>
        <button type="button" class="btn btn-primary btn-block" id="add">添加</button>
      </form>
    </div>
    <div>
      <table class="table">
        <thead>
          <tr>
            <th>学生账号</th>
            <th>密码</th>
            <th>登录日期</th>
          </tr>
        </thead>
        <tbody id="content">
        </tbody>
      </table>
    </div>
  </body>

</html>

下一篇:SpringMVC-16-拦截器(Interceptor)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123887.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!