spring 自定义参数解析器

原创
2018/12/10 20:58
阅读数 149

一、自定义参数解析器说明

        spring最为优秀的地方在于,它的设计方式。依赖注入的bean管理方式、和面向接口编程的设计方式。很多模块或者功能,它提供了接口规范,和默认实现。开发者可以很方便的去自己实现它定义的接口,就具备了相应的功能。spring mvn 的自定义参数解析器,就是这样的设计思想,它提供了默认的实现。但是你可以自定义自己的实现方式。这使得spring 大受欢迎。

二、自定义参数解析器

    用途说明:spring mvc 默认是不能接收List<User> list 这样的参数的,但是我们可以自己定义参数解析器。来实现相应的功能。

    1、以spring boot为例,首先定义一个参数解析器。

package com.github.dgw.config;

import com.github.dgw.annotation.List;
import com.github.dgw.annotation.Page;
import com.github.dgw.common.JsonUtil;
import com.github.dgw.common.PageInfo;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.WebDataBinder;
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.util.ArrayList;

@Component
public class ListArgumentsResolver implements HandlerMethodArgumentResolver {

    /**
     * 解析器是否支持当前参数
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        // 指定参数如果被应用MyParam注解,则使用该解析器。
        // 如果直接返回true,则代表将此解析器用于所有参数
        return methodParameter.hasParameterAnnotation(List.class);
    }


    /**
     * 将request中的请求参数解析到当前Controller参数上
     * @param methodParameter  需要被解析的Controller参数,此参数必须首先传给{@link #supportsParameter}并返回true
     * @param modelAndViewContainer 当前request的ModelAndViewContainer
     * @param nativeWebRequest 当前request
     * @param webDataBinderFactory 生成{@link WebDataBinder}实例的工厂
     * @return
     * @throws Exception
     */
    @Nullable
    @Override
    public Object resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, @Nullable WebDataBinderFactory webDataBinderFactory) throws Exception {
        //获取HttpServletRequest
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);

        //获取方法参数注解
        List methodAnnotation = methodParameter.getParameterAnnotation(List.class);
        //获取注解value字段
        String value = methodAnnotation.value();
        Class<?> clazz=methodAnnotation.clazz();
        String jsonList = request.getParameter(value);
        return JsonUtil.jsonToList(jsonList, clazz);
    }
}

    2、创建一个web 配置类

    

package com.github.dgw.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.annotation.Resource;
import java.util.List;

@Configuration
public class WebConfig extends WebMvcConfigurationSupport{

    @Resource
    private PageArgumentsResolver pageArgumentsResolver;

    @Resource
    private ListArgumentsResolver listArgumentsResolver;

    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(pageArgumentsResolver);
        argumentResolvers.add(listArgumentsResolver);
        super.addArgumentResolvers(argumentResolvers);
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
}

3、在Controller中接受参数进行测试

	@RequestMapping(value = "saveUser", method = {RequestMethod.POST })
	@ResponseBody
	public void saveUsers(@com.github.dgw.annotation.List(value = "userList",clazz = User.class) List<User> userList) {
		for (User user:userList) {
			System.out.println(user.toString());
		}
	}

4、User类

package com.github.dgw.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.github.dgw.common.JsonUtil;

import java.io.Serializable;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Serializable{
    private String name;
    private String pwd;

    public User() {
    }

    public User(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{name=" + name + ", pwd=" + pwd + "}";
    }

}

 

三、进行测试

1、前端请求

 

2、后端接收

参考文献:https://www.jianshu.com/p/0347bdde0c6d

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部