自定义参数解析器,通过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了。