工作生活

mvc参数解析器

2019-07-02  本文已影响0人  dwwl

HandlerMethodArgumentResolver 参数解析器

附:demo的gitHub地址:

https://github.com/Fly0708/smLearn/tree/master/arguresolver/src/main/java/com/mpt/arguResolver

springMVC中,controller层中的方法中经常会有@RequestParam,@PathVariable这种注解。‘

HandlerMethodArgumentResolver参数解析器可以结合拦截器进行使用,经过自己测试,其执行流程是先被拦截器拦截,再经过参数解析器的处理,

实现接口HandlerMethodArgumentResolver 需要实现两个方法

supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument
resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。

简单Demo(SpringBoot项目 启动器:spring-boot-starter-web)

注解:@LoginedUser

package com.mpt.arguResolver.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginedUser {

}

拦截器:AuthorityInterceptor.java(springBoot拦截器的拦截路径在配置类中配置)

package com.mpt.arguResolver.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
@Component
public class AuthorityInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
}

参数解析器:LoginUserHandlerMethodArgumentResolver.java

package com.mpt.arguResolver.resolver;

import com.mpt.arguResolver.anno.LoginedUser;
import com.mpt.arguResolver.pojo.User;
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.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.lang.reflect.Method;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver
{

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        LoginedUser loginedUser = parameter.getParameterAnnotation(LoginedUser.class);
        boolean isAssign = User.class.isAssignableFrom(parameter.getParameterType());//检验isAssignableFrom方法
        return (loginedUser != null && isAssign);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Method method = parameter.getMethod();//检验能不能获得参数被注解的参数
        Object name = webRequest.getParameter("name");
        if (name == null) {
            return null;
        }
        User user = new User();
        user.setName((String) name);
        user.setAge("20");
        return user;//这里为了测试方便直接返回一个User对象,实际写逻辑,比如查数据库
    }
}

参数解析器中先执行supportsParameter()方法,判断被拦截器拦截的方法中的参数(依次执行supportsParameter() resolveArgument() ,方法中有两个参数就会执行两遍)。

拦截器 参数解析器配置类:WebMvcConfig.java

package com.mpt.arguResolver.config;

import com.mpt.arguResolver.interceptor.AuthorityInterceptor;
import com.mpt.arguResolver.resolver.LoginUserHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private LoginUserHandlerMethodArgumentResolver loginUserResolver;

    @Autowired
    private AuthorityInterceptor authorityInterceptor;

      @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器
        registry.addInterceptor(authorityInterceptor).addPathPatterns("/**");
    }
    
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        //注册参数解析器
        resolvers.add(loginUserResolver);
    }
}

实体类:User.java

package com.mpt.arguResolver.pojo;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
public class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

UserController.java

package com.mpt.arguResolver.controller;

import com.mpt.arguResolver.anno.LoginedUser;
import com.mpt.arguResolver.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author huangQiChang
 * @date 2019/7/2
 */
@RestController
public class UserController {

    @GetMapping("/test")
    public User test(@LoginedUser User user,String haha) {
        return user;
    }
}

测试:访问test方法,方法返回经过参数解析器处理后的User对象,

spring中的具体执行流程还需要以后研究

上一篇下一篇

猜你喜欢

热点阅读