1.自定义参数解析器
1.1.HandlerMethodArgumentResolver介绍
在Spring MVC中,HandlerMethodArgumentResolver是一个接口,用于解析处理方法(handler method)的参数。它允许自定义参数的解析过程,以便从请求中提取参数值,并将其传递给处理方法。
当Spring MVC接收到一个请求时,它会尝试匹配请求的URL路径和HTTP方法到相应的处理方法。在执行处理方法之前,Spring MVC会检查方法的参数,并根据参数的类型和注解来解析参数值。这是通过HandlerMethodArgumentResolver接口的实现类来完成的。
HandlerMethodArgumentResolver接口定义了以下方法:
boolean supportsParameter(MethodParameter parameter): 该方法确定是否支持解析给定的方法参数。可以根据参数类型、注解或其他条件来确定是否支持解析该参数。
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception: 该方法用于解析方法参数的值。可以根据需要从请求、会话、Cookie等获取参数的值,并将其转换为适当的类型。
通过自定义HandlerMethodArgumentResolver的实现类,可以扩展Spring MVC的参数解析功能,以满足特定的业务需求。例如:可以实现一个解析器来提取JWT令牌并验证其有效性,然后将解析后的用户信息传递给处理方法。
总结:HandlerMethodArgumentResolver是Spring MVC中的一个接口,用于自定义处理方法参数的解析过程。通过实现该接口,可以扩展参数解析功能,以满足特定的业务需求。
1.2.自定义参数解析器
1.2.1.创建自定义参数解析类
创建自定义参数解析类UserArgumentResolver,并实现HandlerMethodArgumentResolver接口:
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
...
}
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
...
}
}
通过自定义参数解析器实现对请求方法参数进行自定义解析,说白了就是对指定方法中的指定参数进行解析,用于登录Token令牌验证。
具体实现思路分析:
通过request请求对象获取存储在cookie中的token令牌;
判断token令牌是否为空,若为空,则抛异常并提示令牌无效;
根据token令牌从redis中获取存储的用户对象信息,若存在,则有效;反之,无效。
1.2.2.注册自定义参数解析器
要使用HandlerMethodArgumentResolver,需要将其注册到Spring MVC配置中。这可以通过使用WebMvcConfigurer接口的addArgumentResolvers方法来完成。如下:
@Component
public class WebConfig implements WebMvcConfigurer {
@Autowired
private UserArgumentResolver userArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userArgumentResolver);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//添加静态资源访问映射
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
1.2.3.验证测试
在IndexController中定义测试方法:
@RequestMapping("/tokenTest")
public void tokenTest(User user){
System.out.println(user);
}
重启项目,访问测试接口。可以发现在没有验证成功的情况下,将提示令牌无效;验证成功的情况下,则可以成功的得到User对象信息。
2.商品详情
配置首页商品详情接口:
@RequestMapping("/queryGoodsByGid")
public ModelAndView queryGoodsByGid(Goods goods){
...
}
然后,请修改proDetail.html页面,展示商品详情信息。
注意:
${goods.goodsTitle!}:只能判断goodsTitle属性是否为空,不能判断goods对象是否为空
${(goods.goodsTitle)!}:既可以判断goods对象是否为空,也可以判断goodsTitle属性是否为空
3.加入购物车
3.1.创建购物车商品实体类
public class ShopCarItem implements Serializable {
//商品编号
private Long gid;
//商品名称
private String goodsName;
//商品价格
private BigDecimal goodsPrice;
//商品图片
private String goodsImg;
//商品数量
private Integer quantity;
}
并在实体类中定义计算商品小计的方法:
/**
* 商品小计计算
* @return
*/
public BigDecimal smallprice(){
BigDecimal num=new BigDecimal(this.quantity);
return num.multiply(this.goodsPrice);
}
BigDecimal类型不能直接通过运算符方式进行加减乘除操作,必须通过它内置的方法进行计算。
3.2.Redis购物车快速入门
本次案例采用Redis的Hash类型实现Redis版本的购物车功能。
首先,在IRedisService中定义以下两个方法:
public interface IRedisService {
/**
* 根据用户ID将商品存储到Redis中
* @param userId 用户ID
* @param shopCarItem 商品对象
*/
void addCart(Long userId, ShopCarItem shopCarItem);
/**
* 根据用户ID获取Redis中的所有商品信息
* @param userId 用户ID
* @return
*/
List<ShopCarItem> getAllCarts(Long userId);
}
addCart方法根据用户ID+商品对象进行存储(采用的是Redis的Hash类型方式)。注意:这里在加入购物车时,要判断是否存在同类型的商品:如果存在,则该商品在购物车中的数量+1;如果不存在,则直接将商品加入到购物车中。
getAllCarts方法根据用户ID获取该用户的Redis购物车信息。
3.3.实现加入购物车功能
第一步:在加入购物车时,必须判断是否已登录状态,只有登录状态的用户才能加入购物车;
第二步:选择指定商品,点击加入购物车将商品;
第三步:加入购物车成功之后,跳转到购物车页面展示购物车中的商品信息;
@Controller
@RequestMapping("/shopCar")
public class ShopCarController {
/**
* 第一步:该方法专门用于购物车购买是否登录验证
* @param user
* @return
*/
@RequestMapping("/check")
@ResponseBody
public JsonResponseBody<?> check(User user){
return new JsonResponseBody<>();
}
/**
* 第二步:加入购物车
* @param user 当前登录对象
* @param gid 商品ID
* @return
*/
@RequestMapping("/add")
@ResponseBody
public JsonResponseBody<?> add(User user,Long gid){
//1.根据商品ID获取商品详情
...
//2.创建ShopCarItem
...
//3.调用Redis加入购物车方法,加入购物车
...
return new JsonResponseBody<>();
}
/**
* 第三步:查询购物车中的商品
* @param user
* @param session
* @return
*/
@RequestMapping("/queryShopCar")
public ModelAndView queryShopCar(User user){
ModelAndView mv=new ModelAndView();
//从Redis中根据用户ID获取购物车商品集合,并返回到前端页面进行展示
...
return mv;
}
}