概述

有些时候我们需要对GET请求的入参做自定义的处理,比较常见的就是字符串反序列化时间类型了,常用的像@DateTimeFormat注解,但是这需要在每个入参的属性上都加上这个注解,比较费手,那么我们就可以注册一个通用的自定义类型转换器来做这个时间的转换。如果是post请求则可以自定义一个参数解析器来处理

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;

(GET请求)自定义类型转换器demo入门认识

使用类型转换器org.springframework.core.convert.converter.Converter做统一时间处理

一个普通的get请求

package com.fchan.controller;import com.fchan.params.TestDateParams;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("selfSpringMVC")
public class SelfSpringMVCController {@GetMapping("testDate")public Object testDate(TestDateParams params){System.out.println(params);return null;}}

一个普通的入参

package com.fchan.params;import lombok.Data;import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;@Data
public class TestDateParams implements Serializable {private static final long serialVersionUID = -6513336502447867393L;private Date date;private LocalDateTime localDateTime;private LocalDate localDate;}

自定义类型转换

package com.fchan.convert;import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;@Component
public class SelfDateConvert implements Converter<String, Date> {@Overridepublic Date convert(String source) {Assert.notNull(source, "时间不能为空");SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");try {return df.parse(source);} catch (ParseException e) {e.printStackTrace();return null;}}
}package com.fchan.convert;import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;@Component
public class SelfLocalDateConvert implements Converter<String, LocalDate> {@Overridepublic LocalDate convert(String source) {Assert.notNull(source, "时间不能为空");DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");return LocalDate.parse(source, df);}
}package com.fchan.convert;import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class SelfLocalDateTimeConvert implements Converter<String, LocalDateTime> {@Overridepublic LocalDateTime convert(String source) {Assert.notNull(source, "时间不能为空");DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");return LocalDateTime.parse(source, df);}
}

将我们的自定义参数转换添加到spring的参数解析链中

package com.fchan.config;import com.fchan.convert.SelfDateConvert;
import com.fchan.convert.SelfLocalDateConvert;
import com.fchan.convert.SelfLocalDateTimeConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;@Configuration
public class WebMvcConfigurerAdapter implements WebMvcConfigurer {@Autowiredprivate SelfDateConvert selfDateConvert;@Autowiredprivate SelfLocalDateConvert selfLocalDateConvert;@Autowiredprivate SelfLocalDateTimeConvert selfLocalDateTimeConvert;@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(selfDateConvert);registry.addConverter(selfLocalDateConvert);registry.addConverter(selfLocalDateTimeConvert);}}

SpringMVC 执行流程

套用一张网图

POST请求参数解析器

所有的参数解析器都实现了HandlerMethodArgumentResolver这个接口

这是一个典型的策略模式接口,判断当前的方法形参类型是否支持,如果支持就使用该实现类的参数解析器对其解析.

org.springframework.web.servlet.DispatcherServlet调用方法前肯定需要解析一下请求中的参数,转成实际controller中的类型

自定义参数解析器demo

平时接收post请求我们都是用的@requestBody接收的请求体,但有些时候想对请求体中的参数在进入controller之前做一些自定义的转换,这个时候我们就可以自己实现一个注解来解析请求体中的参数。

还是以上面类型转换器中的入参为例,只是这回把入参放入http body中去.

自定义注解

package com.fchan.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentTime {}

自定义解析器解析http body

package com.fchan.methodArgumentResolver;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fchan.annotation.CurrentTime;
import com.fchan.params.TestDateParams;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;@Component
public class CurrentTestTimeHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {@Autowiredprivate ObjectMapper myObjectMapper;/*** 用于判定是否需要处理该参数分解,返回 true 为需要,并会去调用下面的方法resolveArgument。*/@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(CurrentTime.class)&&parameter.getParameterType().isAssignableFrom(TestDateParams.class);}/*** 真正用于处理参数分解的方法,返回的 Object 就是 controller 方法上的形参对象。*/@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {//webRequest.getHeader("xxx")//Map<String, String[]> parameterMap = webRequest.getParameterMap();String requestBody = getRequestBody(webRequest);return myObjectMapper.readValue(requestBody, TestDateParams.class);}private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";private String getRequestBody(NativeWebRequest webRequest){HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST);if (jsonBody == null) {try {jsonBody = IOUtils.toString(servletRequest.getInputStream());webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST);} catch (IOException e) {throw new RuntimeException(e);}}return jsonBody;}}

注册解析器

成功解析

springmvc自定义参数解析器/类型转换器相关推荐

  1. springmvc自定义参数解析器

    由于开发中一般使用参数提交方式是json格式,对于单个参数的传递使用无法接收只能自定义参数解析器处理 springmvc的自定义参数解析器实现HandlerMethodArgumentResolver ...

  2. springMvc(实现HandlerMethodArgumentResolver)自定义参数解析器

    由于之前用@RequestParam无法接收request payload 正文格式为json格式的字符串,只能使用@RequestBody整个接收,觉得麻烦,但是spring自带的参数解析器不具有这 ...

  3. Spring自定义参数解析器

      虽然Spring提供了比较完善的参数解析器,但是对于一些特殊的数据类型我们还是需要进行特殊处理,这样会提高代码的复杂度,增加冗余的代码,降低代码可读性和可维护性.所以自定义参数解析器是一个很好的解 ...

  4. Spring MVC自定义类型转换器Converter、参数解析器HandlerMethodArgumentResolver

    文章目录 一.前言 二.类型转换器Converter 1.自定义类型转换器 三.参数解析器 1.自定义分页参数解析器 2.自定义注解参数解析器 一.前言 Spring MVC源码分析相关文章已出: S ...

  5. SpringMVC的视图解析器

    文章目录 SpringMVC的自定义视图解析器 [1] SpringMVC的视图解析器 [2] SpringMVC的自定义视图解析器 SpringMVC自定义视图解析器的使用 [1] 目前项目资源的声 ...

  6. SpringMVC 参数解析器

    一.问题 springMVC对于下面这种接口,参数是怎么解析的: @GetMapping("/hello/{id}") public void hello3(@PathVariab ...

  7. spring MVC使用自定义的参数解析器解析参数

    目录 写在前面 编写自定义的参数解析器解析请求参数 项目结构 定义注解 实体类 controller 定义参数解析器 注册参数解析器 启动项目 发起请求查看结果 写在前面 如果还有小伙伴不知道spri ...

  8. SpringBoot--网上商城项目(自定义的参数解析器、购物车后台前台功能、商品详情页)

    目录 一.自定义的参数解析器 关于Mybatis-plus时间字段代码生成问题 报错信息:Caused by: java.lang.IllegalStateException: No typehand ...

  9. 拦截器HandlerInterceptor+方法参数解析器HandlerMethodArgumentResolver用于统一获取当前登录用户信息

    文章目录 前言 一.拦截器+方法参数解析器 是什么? 二.具体实现步骤 1.自定义权限拦截器LoginInterceptor拦截所有request请求,并将token解析为currentUser,最终 ...

最新文章

  1. 五连阳回调买入法_“4连阳+1阴”这种股票,吃透主升浪!挣得万贯家财
  2. python 多线程 全站小说_多线程下载小说
  3. 架构师养成之道-02-jvm原理
  4. oracle 12c chad,ORACLE 12.2RAC之问题 ora.chad OFFLINE
  5. java 数据结构 快速入门_Java 数据结构快速入门
  6. geometry-api-java 学习笔记(二)点 Point
  7. 【树莓派】Linux指令使用记录
  8. python的设计哲学是优雅明确简单_Python简单教程
  9. 程序默认在副屏显示_树莓派使用 OLED 屏显示图片及文字
  10. android 恢复出厂设置代码流程(Good!)
  11. vue-router 报错:Navigation cancelled from“/…“ to “/…“ with a new navigation.
  12. 计算一路话音消耗的带宽
  13. 日光能和电池两用计算机,为什么太阳照射的光可以给太阳能转化为电,而我们的日光灯却不行?...
  14. swiper滑动切换变换样式,实时显示当前索引
  15. win10显示无法连接到Internet但是能上网
  16. Latex 论文引用
  17. 射击末世--代理模式
  18. 阿里云服务器安装云助手客户端
  19. [计算机网络]第一章——计算机网络和因特网
  20. office2010下载大全

热门文章

  1. C#封装-里氏替换原则
  2. 微软免费杀毒软件Morro开始测试 征求定名
  3. php try catch 应用
  4. 烤箱和空气炸锅有什么区别
  5. MAXPLUS教程 - 第2章CPLD和FPGA
  6. PostgreSQL事物隔离级别之可重复读
  7. 关于数字电路与模拟电路隔离
  8. SpringBoot技术实践-SpELEL表达式
  9. 查询hba卡wwn号
  10. 慧创脑科学第八期直播精彩回顾丨fNIRS与神经退行性疾病