1. 程式人生 > >SpringMVC通過HandlerMethodArgumentResolver自定義引數解析

SpringMVC通過HandlerMethodArgumentResolver自定義引數解析

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