SpringMVC拦截所有Controller请求,实现自定义参数

1.自定义参数分解器

重写addArgumentResolvers方法生产参数分解器

需要实现HandlerMethodArgumentResolver接口,
supportsParameter方法返回的是当前方法实例
resolveArgument方法返回时对象类型

上代码:

// An highlighted block

@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private MiaoShaUserService userService;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
      Class<?> clazz =    methodParameter.getParameterType() ;
      return clazz == MiaoshaUser.class ;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest webRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        /**
         *  threadlocal  线程安全
         */
        return UserContext.getUser();
    }

}

2.重写拦截器方法

需要继承HandlerInterceptorAdapter

需要注意的是三个方法: preHandle postHandle afterCompletion

perHandle:执行controller方法之前调用,通常做登录之前的处理,共同方法,可以获取方法的注解response,request之类
postHandle:执行controller后,返回modelAndView方法,但未进行页面渲染的时候调用。
afterCompletion:服务器端已经执行完毕,页面渲染完毕后执行
上代码:

// An highlighted block

@Service
public class AccessInterceptor  extends HandlerInterceptorAdapter{

	private static Logger logger = LoggerFactory.getLogger(AccessInterceptor.class);

	@Autowired
	MiaoShaUserService userService;

	@Autowired
	RedisService redisService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		/**
		 * 获取调用 获取主要方法
		 */
		if(handler instanceof HandlerMethod) {
			logger.info("打印拦截方法handler :{} ",handler);
			HandlerMethod hm = (HandlerMethod)handler;
			MiaoshaUser user = getUser(request, response);
			UserContext.setUser(user);
			AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);

			if(accessLimit == null) {
				return true;
			}

			int seconds = accessLimit.seconds();
			int maxCount = accessLimit.maxCount();
			boolean needLogin = accessLimit.needLogin();
			String key = request.getRequestURI();
			if(needLogin) {
				if(user == null) {
					render(response, SESSION_ERROR);
					return false;
				}
				key += "_" + user.getNickname();
			}else {

			}
			AccessKey ak = AccessKey.withExpire(seconds);
			Integer count = redisService.get(ak, key, Integer.class);
	    	if(count  == null) {
	    		 redisService.set(ak, key, 1);
	    	}else if(count < maxCount) {
	    		 redisService.incr(ak, key);
	    	}else {
	    		render(response, ACCESS_LIMIT_REACHED);
	    		return false;
	    	}
		}
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		super.afterCompletion(request, response, handler, ex);
		UserContext.removeUser();
	}

	private void render(HttpServletResponse response, ResultStatus cm)throws Exception {
		response.setContentType("application/json;charset=UTF-8");
		OutputStream out = response.getOutputStream();
		String str  = JSON.toJSONString(ResultObject.error(cm));
		out.write(str.getBytes("UTF-8"));
		out.flush();
		out.close();
	}

	private MiaoshaUser getUser(HttpServletRequest request, HttpServletResponse response) {
		String paramToken = request.getParameter(MiaoShaUserService.COOKIE_NAME_TOKEN);
		String cookieToken = getCookieValue(request, MiaoShaUserService.COOKIE_NAME_TOKEN);
		if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
			return null;
		}
		String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
		return userService.getByToken(response, token);
	}

	private String getCookieValue(HttpServletRequest request, String cookiName) {
		Cookie[]  cookies = request.getCookies();
		if(cookies == null || cookies.length <= 0){
			return null;
		}
		for(Cookie cookie : cookies) {
			if(cookie.getName().equals(cookiName)) {
				return cookie.getValue();
			}
		}
		return null;
	}

2.实现WebMvcConfigurer

需要实现两个方法

addinterceptors:添加拦截器方法
addArgumentResolvers:添加参数解调器
上代码:

// An highlighted block

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    UserArgumentResolver resolver;

    @Autowired
    private AccessInterceptor interceptor;
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(resolver);
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor);
    }

然后就可以在controllor方法里写参数调用,例如这样:

// An highlighted block

    @AccessLimit(seconds = 5, maxCount = 5, needLogin = true)
    @RequestMapping(value="/{path}/do_miaosha", method= RequestMethod.POST)
    @ResponseBody
    public ResultObject<Integer> miaosha(Model model, MiaoshaUser user, @PathVariable("path") String path,
                                         @RequestParam("goodsId") long goodsId) {

miaoshaUser就是通过参数解调器实现的。

以上

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了。对于你的问题,我可以这样回答: 利用 SpringMVC 拦截器可以控制 Controller 返回值。拦截器是一种 AOP 的技术,可以在请求处理过程中对请求进行拦截和处理,如校验用户权限、记录请求日志等。在处理 Controller 返回值时,可以通过拦截器对返回值进行处理,如对返回值进行加密、压缩等操作。 具体实现步骤如下: 1. 自定义一个拦截器类并实现 HandlerInterceptor 接口。 2. 在 Spring 配置文件中注册拦截器。 3. 在拦截器中重写 preHandle() 和 postHandle() 方法,分别在请求处理前和请求处理后进行拦截和处理。 4. 在 postHandle() 方法中获取 Controller 返回值并进行处理,如加密、压缩等操作。 下面是一个简单的示例代码: ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理前进行拦截和处理 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求处理后进行拦截和处理 if (modelAndView != null) { // 对返回值进行加密、压缩等操作 } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在请求完成后进行拦截和处理 } } ``` 在 Spring 配置文件中注册拦截器: ```xml <mvc:interceptors> <bean class="com.example.MyInterceptor"/> </mvc:interceptors> ``` 这样就可以利用 SpringMVC 拦截器控制 Controller 返回值了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值