SpringMVC通過HandlerMethodArgumentResolver自定義引數解析
阿新 • • 發佈:2018-12-17
今天新開發了一個專案,用來把公司其他服務調大資料介面都集中到這個新的服務中。請求引數都是加密的,因此請求參中有一些跟業務無關的資料,那麼怎麼能夠實現只要和業務有關的資料呢?
其他服務傳過來的資料是通過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自定義引數解析的方法,希望對大家有所幫助