_Spring MVC获取参数和自定义参数类型转换器及编码过滤器

2023-11-18 16:39:45 浏览数 (1)

一、使用Servlet原生对象获取参数

        SpringMVC也支持使用Servlet原生对象,在方法参数中定义HttpServletRequest 、HttpServletResponse 、 HttpSession 等类型的参数即可直接在方法中使用。

1.1 控制器方法

代码语言:javascript复制
// 使用Servlet原生对象
    @RequestMapping("c1/param8")
    public void servletParam(HttpSession session,HttpServletRequest request, HttpServletResponse response){
        // 原生对象获取参数
        System.out.println(request.getParameter("name"));
        System.out.println(response.getCharacterEncoding());
        System.out.println(session.getId());
    }

        这个就是一个很经典的利用request内置对象获取参数了。请求之后在控制台打印参数和编码方式还有对应的sessionId。 访问路径:http://localhost:8080/c1/param8?name=LYL

1.2 测试结果

  OK,可以看得出来是已经成功把参数值和编码方式和sessionId给查询出来了         一般情况下,在SpringMVC中都有对Servlet原生对象的方法的替代,推荐使SpringMVC的方式代替Servlet原生对象。

二、自定义参数类型转换器

前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:

代码语言:javascript复制
// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
    System.out.println(username " " age);
}

但在某些情况下,无法将字符串转为需要的类型,如:

// 自定义转换日期格式字符串

@RequestMapping("c1/param9")

public void dataParam(Date birthday){

    System.out.println(birthday);

}

此时我们测试一下看看是什么结果:

控制台输出: 

报错原因:

[WARNING]Resolved[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2025-01-01'; nested exception is java.lang.IllegalArgumentException]  具体意思就是:[org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:未能将类型为“java.lang.String”的值转换为所需类型“java.util.Date”;嵌套异常为org.springfframework.core.covert.ConversionFailedException:无法将值“2025-01-01”从类型[java.lang.SString]转换为类型[java.util.Date];嵌套异常为java.lang.IllegalArgumentException]

2.1 编写类型转换器类

        由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符串转换成日期类型。比如参数格式为 birthday=2025-01-01 时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。 首先得定义类型转换器类,实现Converter接口。写法如下:  

代码语言:javascript复制
package com.example.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DataConverter implements Converter<String, Date> {

    /**
     * 转换方法
     * @param s 转换前的数据
     * @return 转换后的数据
     */
    @Override
    public Date convert(String s) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
        Date date = null;
        try{
            date = sdf.parse(s);
        } catch (ParseException e) {
            System.out.println("转换成日期格式出错了!");
            e.printStackTrace();
        }
        return date;
    }
}

2.2 注册类型转换器对象 

代码语言:javascript复制
<!-- 配置转换器工厂 -->
    <bean id="dateConverter" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <!-- 转换器集合 -->
        <property name="converters">
            <set>
                <!-- 自定义转换器 -->
                <bean class="com.example.converter.DataConverter"></bean>
            </set>
        </property>
    </bean>
    <!-- 使用转换器工厂 -->
    <mvc:annotation-driven conversion-service="dateConverter"></mvc:annotation-driven>

OK,加了上面这些我们再运行测试一遍看看控制能否成功接收 

2.3 测试结果 

可以看到报的是404错误,没有找到这个页面,而不是400了

OK,控制台也成功打印出来了。 

三、编码过滤器

在传递参数时,tomcat8以上能处理get请求的中文乱码,但不能处理post请求的中文乱码

3.1 JSP表单

代码语言:javascript复制
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>专属页面</title>
</head>
<body>
  <form action="/c1/param3" method="post">
    <table>
      <tr>
        <th>id:</th>
        <td><input name="id"/></td>
      </tr>
      <tr>
        <th>姓名:</th>
        <td><input name="name"/></td>
      </tr>
      <tr>
        <th>性别:</th>
        <td><input name="sex"/></td>
      </tr>
      <tr>
        <th>住址:</th>
        <td><input name="address.info"/></td>
      </tr>
      <tr>
        <th>邮编:</th>
        <td><input name="address.postcode"/></td>
      </tr>
      <tr align="center">
        <td><input type="submit"/></td>
      </tr>
    </table>
  </form>
</body>
</html>

这里是一个表单提交的页面

3.2 控制器方法

控制器方法我就沿用了之前的,如下: 

代码语言:javascript复制
    @RequestMapping("c1/param3")
    public void objParam2(Student student){
        System.out.println(student);
    }

3.3 配置过滤器

        SpringMVC提供了处理中文乱码的过滤器,在web.xml中配置该过滤器即可解决中文乱码问题:添加如下配置:

代码语言:javascript复制
<!-- SpringMVC中提供的字符编码过滤器,放在所有过滤器的最上方 -->
  <filter>
    <filter-name>encFilter</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>encFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3.4 测试结果 

   提交上述信息,看看控制台打印有没有乱码,如果没有乱码,则说明字符编码过滤器配置成功。 

  OK,说明确实是可以了,并且表单提交的name属性和Student属性对应的话,也是可以直接赋值给对应的参数的。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞