Spring自定义参数解析器

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

  还有一点需要注意的是,本篇博客自定义参数解析器使用的方法是通过继承AbstractNamedValueMethodArgumentResolver类实现的,而我们经常使用的注解@RequestParam的参数解析器也是继承自AbstractNamedValueMethodArgumentResolver类。当然还有一种解决方案是通过实现HandlerMethodArgumentResolver接口来实现,但是区别的是如果通过HandlerMethodArgumentResolver接口来实现的话,在解析器中会获取到所有的参数,而我们还需要另外写代码在一串参数中的到我们需要处理的参数再进行处理。而通过继承AbstractNamedValueMethodArgumentResolver类来实现的话,因为AbstractNamedValueMethodArgumentResolver类本身就实现了HandlerMethodArgumentResolver接口,所以我们在参数解析器中得到的是一个一个的参数,处理起来相对简单。

  本项目是用SpringBoot写的,自定义用于将字符串解析为Date时间类型的参数解析器。

1、项目目录结构
这里写图片描述

2、RequestDateParam

package com.xyc.argumentresolver.annotation;

import com.xyc.argumentresolver.constant.DateFormatPattern;

import java.lang.annotation.*;

/**
 * Created by xyc on 2017/7/27 0027.
 */
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestDateParam {
    String value() default "";

    DateFormatPattern pattern() default DateFormatPattern.YYYY_MM_DD_HH_MM_SS;

    boolean required() default true;
}

3、DateFormatPattern

package com.xyc.argumentresolver.constant;

/**
 * Created by xyc on 2017/7/29 0029.
 */
public enum DateFormatPattern {
    YYYY_MM_DD("yyyy-MM-dd"), YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd hh:mm:ss");
    private String value;

    DateFormatPattern(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

4、ArgumentResolverApplication

package com.xyc.argumentresolver;

import com.xyc.argumentresolver.resolver.RequestDateParamMethodArgumentResolver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@SpringBootApplication
public class ArgumentResolverApplication extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(ArgumentResolverApplication.class, args);
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new RequestDateParamMethodArgumentResolver());    //添加自定义参数解析器
    }
}

5、ArgumentResolverController

package com.xyc.argumentresolver.controller;

import com.xyc.argumentresolver.annotation.RequestDateParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * Created by xyc on 2017/7/27 0027.
 */
@RestController
@RequestMapping("/argumentResolver")
public class ArgumentResolverController {
    @RequestMapping(value = "/requestDateParamTest", method = RequestMethod.GET)
    public String requestDateParamTest(@RequestDateParam Date date) {
        System.out.println(date);
        return "success value is " + date;
    }
}

6、RequestDateParamMethodArgumentResolver

package com.xyc.argumentresolver.resolver;

import com.xyc.argumentresolver.annotation.RequestDateParam;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver;

import javax.servlet.ServletException;
import java.text.SimpleDateFormat;

/**
 * Created by xyc on 2017/7/29 0029.
 */
@Component
public class RequestDateParamMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
    /**
     * 获取当前参数的注解信息
     *
     * @param methodParameter 需要被解析的Controller参数
     * @return
     */
    @Override
    protected NamedValueInfo createNamedValueInfo(MethodParameter methodParameter) {
        RequestDateParam annotation = (RequestDateParam) methodParameter.getParameterAnnotation(RequestDateParam.class);
        return new NamedValueInfo(annotation.value(), annotation.required(), (String) null);
    }

    /**
     * 在这里进行参数的类型转换
     *
     * @param s
     * @param methodParameter  需要被解析的Controller参数
     * @param nativeWebRequest 当前request
     * @return 转换后的参数值
     * @throws Exception
     */
    @Override
    protected Object resolveName(String s, MethodParameter methodParameter, NativeWebRequest nativeWebRequest) throws Exception {
        String content = nativeWebRequest.getParameter(s);
        if (content == null) {
            return null;
        } else {
            try {
                RequestDateParam annotation = methodParameter.getParameterAnnotation(RequestDateParam.class);
                SimpleDateFormat dateFormat = new SimpleDateFormat(annotation.pattern().getValue());
                return dateFormat.parse(content);
            } catch (Exception e) {
                throw new IllegalArgumentException("Date format conversion error", e);
            }
        }
    }

    /**
     * 解析器是否支持当前参数
     *
     * @param methodParameter 需要被解析的Controller参数
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(RequestDateParam.class);
    }

    /**
     * 当前参数值为空且注解的默认值也为空则抛出异常
     *
     * @param name      参数名
     * @param parameter 需要被解析的Controller参数
     * @throws ServletException
     */
    @Override
    protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException {
        throw new MissingServletRequestParameterException(name, parameter.getParameterType().getSimpleName());
    }
}

注意:如果是SpringMVC项目,则需要将参数解析器注册到HandlerAdapter中

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">

        <property name="requestDateParamMethodArgumentResolver">
            <list>
                <bean class="com.xyc.argumentresolver.resolver.RequestDateParamMethodArgumentResolver" />
            </list>
        </property>
        <property name="order" value="0" />
    </bean>

github地址:https://github.com/xiayongchao/ArgumentResolver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值