SpringMVC注解的方式自定义参数处理器

版权声明:文章来源-苏亿_blog https://blog.csdn.net/qq_40325734/article/details/81814467

关于SpringMVC的处理器拦截器:

SpringMVC的拦截器(面向切面编程)底层使用的是AOP动态代理:

拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

Struts2的是File过滤器:

过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.。

关于拦截器和过滤器区别LINK:

LINK: https://blog.csdn.net/evilcry2012/article/details/79737161

使用注解和代码完成SpringMVC的自定义参数处理器:

将自定义的拦截器加入到处理器的队列

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.WebMvcConfigurerAdapter;
import java.util.List;

/**
 * SpringMVC配置处理器
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    UserArgumentResolver userArgumentResolver;

    /**
     * 将UserArgumentResolver将入到处理器队列中来
     * @param argumentResolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(userArgumentResolver);
    }
}

自定义参数处理器:

supportsParameter方法对所有Controller层接口方法判断此解析器是否支持此类型,然后再调用resolveArgument进行具体的参数处理

import com.demo.miaosha.domain.MiaoshaUser;
import com.demo.miaosha.service.MiaoshaUserService;
import com.demo.miaosha.utils.CooKieUtil;
import org.springframework.beans.factory.annotation.Autowired;
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.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 这个自定义的参数处理器,对请求的cookie进行处理,cookie中key为token的值
 * 做为redis缓存中用户信息的key进行查询,查询到的用户信息MiaoshaUser对象返回
 */
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    MiaoshaUserService miaoshaUserService;

    /**
     * 所有方法中的参数都需要调用此方法判断此解析器是否支持此参数
     * @param parameter 请求参数
     * @return 支持返回true,不支持返回false
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Class<?> parameterType = parameter.getParameterType();
        return parameterType == MiaoshaUser.class;
    }

    /**
     * 在supportsParameter(parameter)方法判断完,方法中的参数解析器是否支持后,
     * 所有请求此路径的方法,调用此方法对请求参数进行处理
     *
     * 将方法参数解析为来自给定请求的参数值。 ,
     * ModelAndViewContainer 提供对*请求的模型的访问。 ,
     * WebDataBinderFactory 提供了一种在需要进行数据绑定和*类型转换时创建 WebDataBinder实例的方法。
     *
     * @param parameter 请求参数(这里的请求参数都是已经调用过上面的supportsParameter判断过解析器是否支持)
     * @param mavContainer 当前请求的ModelAndViewContainer
     * @param webRequest 当前的请求
     * @param binderFactory 用于创建 WebDataBinder 实例的工厂
     * @return 用户信息
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //获取请求和响应对象
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpServletResponse response = webRequest.getNativeRequest(HttpServletResponse.class);

        //由于手机端和电脑端的差异,这段代码除了return哪里是调用查询redis缓存中的用户信息,其他的都是获取到cookie的值以及对他的判断
        //从请求参数中获取cookie的值
        String paramToken = request.getParameter(CooKieUtil.COOKIE_NAME_TOKEN);
        //正常从请求中获取Cookie[]来获取cookie对象,调用getValue()方法获取值
        String cookieToken = getCookieValue(request, CooKieUtil.COOKIE_NAME_TOKEN);

        //判断是否为空
        if (StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)){
            return null;
        }

        String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;

        //获取用户信息
        return miaoshaUserService.queryUserLogin(response,token);
    }

    /**
     * 获取指定cookie的值
     * 正常从请求中获取Cookie[]来获取cookie对象,调用getValue()方法获取值
     * @param request 请求
     * @param cookieNameToken 需要获取的cookie的key
     * @return cookie的value
     */
    private String getCookieValue(HttpServletRequest request, String cookieNameToken) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie:cookies){
            if (cookie.getName().equals(cookieNameToken)){
                return cookie.getValue();
            }
        }
        return null;
    }
}

Controller层代码:

    /**
     * 登录
     * @param vo 前端返回过来用户账号和密码
     * @return 登录成功的信息or失败信息
     */
    @RequestMapping(path="/do_login",method=RequestMethod.POST)
    @ResponseBody
    public Result do_login(MiaoshaUser user, HttpServletResponse response, @Valid LoginVo vo){
        System.out.println(user);
        //判断用户是否已登录,在自定义的参数处理器中进行了处理
        if (user != null){
            return Result.Failure(ResultEnum.USER_YET_LOGIN);
        }

        log.info(vo.toString());
        boolean loginResult = miaoshaUserService.login(response,vo);
        return Result.SUCCESS(ResultEnum.SUCCESS,loginResult);
    }

自定义参数处理器完成分页LINK:

LINK: https://www.jianshu.com/p/f2f8b816b3a9

猜你喜欢

转载自blog.csdn.net/qq_40325734/article/details/81814467