今天新开发了一个项目,用来把公司其他服务调大数据接口都集中到这个新的服务中。请求参数都是加密的,因此请求参中有一些跟业务无关的数据,那么怎么能够实现只要和业务有关的数据呢?
其他服务传过来的数据是通过form形式保存在TranHead和TranBody中,其中TranBody中保存了加密之后的请求参数。
首先,通过拦截器,对加密的数据进行解密
public class IntfaceSecurityInterceptor extends HandlerInterceptorAdapter {
public static final Log logger = LogFactory.getLog(IntfaceSecurityInterceptor.class);
@Resource
private IASysClientKeyService aSysClientKeyService;
@Resource
private IASysPortLogService aSysPortLogService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
…………
request.setAttribute("clientKey", client);
request.setAttribute("aSysPortLog", log);
request.setAttribute("transHead", head);
request.setAttribute("transBody", transBody);
return super.preHandle(request, response, handler);
…………
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}
}
拦截器对数据进行解密之后,放在了”clientKey” “aSysPortLog” “transHead” “transBody”中,这里跟业务相关的数据都保存在transBody中,那么我怎么实现只接收transBody中的数据呢?
这里需要实现HandlerMethodArgumentResolver接口,代码如下:
public class TransBodyArgumentResolve implements HandlerMethodArgumentResolver{
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(TransBody.class);
}
@SuppressWarnings("unchecked")
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String)request.getAttribute("transBody");
//判断请求参数类型是否为MapWrap
if(MapWrap.class.isAssignableFrom(parameter.getParameterType())){
MapWrap<String,Object> wrap = (MapWrap<String, Object>) parameter.getParameterType().newInstance();
Map<String, Object> map = JSON.parseObject(jsonBody, new TypeReference<Map<String,Object>>(){});
wrap.setInnerMap( map);
return wrap;
}
//请求参数类型为其他(自己组装的实体)
Type paramType = parameter.getGenericParameterType();
Object result = JSON.parseObject(jsonBody, paramType);
return result;
}
}
在supportsParameter方法中判断请求参数是否被HandlerMethodArgumentResolver所支持,方法参数MethodParameter 里面包含了请求参数的信息 例如:Method、Constructor、Annotation等信息,
上述的supportsParameter方法表示如果请求参数有@TransBody 注解,那么该请求可以被HandlerMethodArgumentResolver支持,就会按照resolveArgument中的方法来处理请求参数。从上述resolveArgument方法中可以看到,之获取了transBody中的参数,然后通过parseObject把json转成MapWrap或者对应的实体类。
TransBody对应的注解如下:
@Target({java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TransBody {
boolean required() default true;
}
以上就是通过实现HandlerMethodArgumentResolver自定义参数解析的方法,希望对大家有所帮助