解析 filter+注解+HandlerMethodArgumentResolver 给控制器函数参数赋值
1
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Sid {
String value() default "sid";
}
2
package com.bimatrix.mobile.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bimatrix.common.ErrorType;
import com.bimatrix.common.I18NResult;
import com.bimatrix.mobile.Writer;
import com.bimatrix.util.TokenUtils;
public class IdentifyVerifyFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(IdentifyVerifyFilter.class);
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
String token = request.getHeader("token");
String[] datas = TokenUtils.verifyToken(token);
if (datas == null || !TokenUtils.getEnv().equals(datas[3])) {
Writer.write(response, I18NResult.failure(ErrorType.STOKEN_ERROR));
} else {
request.setAttribute("uid", Long.valueOf(datas[0]));
request.setAttribute("sid", Long.valueOf(datas[1]));
request.setAttribute("did", datas[2]);// 放到request 里面 供后面第三步从request里面取值
chain.doFilter(request, response);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
Writer.write(response, I18NResult.exception(ErrorType.SERVER_ERROR));
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
这里存到了 request 里面 而没有放到session里面 可能是单次使用 其实如果使用session的话 更好 不需要每次解析。。呵呵
3 应用
@RequestMapping("/business/uploadCid")
@ResponseBody
public Output uploadCid(@Uid long uid, @RequestParam("cid") String cid) {
userService.uploadCid(uid, cid);
return Result.success();
}
当出现uid这种地方 就会去步骤4里面解析uid
4
package com.bimatrix.mobile.controller.resolver;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
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;
public class SidArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(Sid.class) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Sid parameterAnnotation = parameter.getParameterAnnotation(Sid.class);
if (parameterAnnotation != null) {
String attributeKey = parameterAnnotation.value();
HttpServletRequest nativeRequest = (HttpServletRequest) webRequest.getNativeRequest();
return nativeRequest.getAttribute(attributeKey);//这里取出步骤2 放进去的uid 的值 X,步骤3
public Output uploadCid(@Uid long uid, @RequestParam("cid") String cid) {
这个long uid 就被 设置为X ,供函数内部使用 该参数
}
return null;
}
}
1-4 的目的 尤其就是1 为了统一获得sid uid的值 从session中后面 就不需要每个controller 函数涉及到解析token
String token = request.getHeader("token"); 这样代码不会controller 每个地方都去解析一次token 代码比较优雅,
如果把request 换成session 效率更高,app端只要登录 请求就不需要每次都去解析token 直接从session里面获取即可以
效率更高
参加下一篇文章
欢迎打赏