Featured image of post 自定义参数解析器,通过SpringMVC自动注入,判断频繁验证问题!如:用户是否登录问题

自定义参数解析器,通过SpringMVC自动注入,判断频繁验证问题!如:用户是否登录问题

自定义参数解析器,通过SpringMVC自动注入,判断频繁验证问题!如:用户是否登录问题

自定义参数解析器,通过SpringMVC自动注入,判断频繁验证问题!如:用户是否登录问题

SpringBoot

参数解析器介绍

参数解析器属于spring-web包中提供的组件,springmvc框架中对应提供了很多参数解析器。例如我们开发的Controller代码如下:

@RestController
@RequestMapping("/user")
public class UserController{
	@PostMapping("/save")
	//此处request对象就是通过Springmvc提供的参数解析器帮我们注入的
	public String saveUser(HttpServletRequest request){
    	return "success";
	}
}

在上面的saveUser方法中,我们声明了一个类型为HttpServletRequest的参数,这个对象就是通过springmvc提供的ServletRequestMethodArgumentResolver这个参数解析器帮我们注入的。同样如果我们需要使用HttpServletResponse对象,也可以直接在方法上加入这个参数即可,此时springmvc会通过ServletResponseMethodArgumentResolver这个参数解析器帮我们注入。

在项目开发中我们也可以根据需要自定义参数解析器,需要实现HandlerMethodArgumentResolver接口:

public interface HandlerMethodArgumentResolver {
	boolean supportsParameter(MethodParameter var1);

	@Nullable
	Object resolveArgument(MethodParameter var1, 
                        @Nullable ModelAndViewContainer var2, 
                        NativeWebRequest var3, 
                        @Nullable WebDataBinderFactory var4) throws Exception;
}

可以看到此接口包含两个接口方法:supportsParameter和resolveArgument。

当supportsParameter方法返回true时,才会调用resolveArgument方法。

自定义参数解析器的使用总结

SpringBoot实战

案例:GoodsController判断用户是否登录

实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
public class User implements Serializable {
	private static final long serialVersionUID = 1L;
    /**
     * 用户ID,手机号码
     */
    private Long id;	
    private String nickname;	
    /**
     * MD5(MD5(pass明文+固定salt)+salt)
     */
    private String password;

    private String salt;
    /**
     * 头像
     */
    private String head;	
    /**
     * 注册时间
     */
    private Date registerDate;	
    /**
     * 最后一次登录事件
     */
    private Date lastLoginDate;	
    /**
     * 登录次数
     */
    private Integer loginCount;
}

Controller

@Controller
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private ISeckillGoodsService iSeckillGoodsService;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @RequestMapping("/toList")
    public String toList(User user, Model model, HttpServletRequest request){
        //1判断用户是否登录
        if (user == null)
            return "login";
        model.addAttribute("user",user);
        //2查询所有秒杀商品信息
        List<SeckillGoodsVo> list = iSeckillGoodsService.tolist();
        model.addAttribute("goodsVoList",list);
        return "goodsList";
    }
}

在形参上写上User,这样SpringMVC就可以自动注入,将验证后的User返回,只需要判断User是否为null即可。

引入依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

自定义MVCConfig实现WebMvcConfigurer接口

@Component
public class MVCConfig implements WebMvcConfigurer {
	@Autowired
	private UserArgumentResolver userArgumentResolver;
	/**
 	* SpringMVC 提供的Controller的参数解析器
 	* @param resolvers
 	*/
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    	boolean add = resolvers.add(userArgumentResolver);
	}
}

实现WebMvcConfigurer接口,重写addArgumentResolvers方法,就可以将自定义的参数解析器注入

自定义UserArgumentResolver实现HandlerMethodArgumentResolver接口

@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType() == User.class;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        String uuid = CookieUtil.getCookieValue(request, "token");
        if (StringUtils.isEmpty(uuid)){
            return null;
        }
	//        Object users = request.getSession().getAttribute(uuid);
	//        if (users == null)
	//            return "login";
    	String userJson = (String) redisTemplate.opsForValue().get("user:uuid:" + uuid);
    	if (userJson == null)
        	return null;
    	User user = JsonUtil.jsonStr2Object(userJson, User.class);
    	return user;
	}
}

最后将判断后的User返回,Controller中就可以拿到判断后的User了。