1. 程式人生 > >使用引數攔截器通過註解直接從JSON物件中獲取資料

使用引數攔截器通過註解直接從JSON物件中獲取資料

場景:當前段傳過來的物件是JSON物件,當時我們使用的時候又是僅僅使用其中的部分欄位值的時候,可以通過實現引數攔截器來為我們自動將JSON中的key值賦值給引數

程式碼

1.自定義註解

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonParam {
    String value() default "";
}

2.實現引數攔截器

public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver {

    private static final String JSON_REQUEST_BODY="JSON_REQUEST_BODY";

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(JsonParam.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        String paramName= Optional.ofNullable(methodParameter.getParameterAnnotation(JsonParam.class).value()).filter(StringUtils::isNotBlank).orElse(methodParameter.getParameterName()).toString();
        return JSONPath.read(getRequestBody(nativeWebRequest),paramName);
    }

    private String getRequestBody(NativeWebRequest webRequest){
        HttpServletRequest servletRequest=webRequest.getNativeRequest(HttpServletRequest.class);
        String jsonBody=(String)servletRequest.getAttribute(JSON_REQUEST_BODY);
        if(jsonBody==null){
            try{
                jsonBody= IOUtils.toString(servletRequest.getInputStream());
                servletRequest.setAttribute(JSON_REQUEST_BODY,jsonBody);
            }catch (IOException e){
                throw new RuntimeException(e);
            }
        }
        return jsonBody;
    }
}

3.註冊引數攔截器
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new JsonPathArgumentResolver());
        super.addArgumentResolvers(argumentResolvers);
    }
}
4.編寫測試controller
@Controller
@RequestMapping("h1")
public class TestController {

    @RequestMapping(value = "h2")
    public @ResponseBody Object testHeaderContext(@RequestParam("sex") int sex, @JsonParam int age, @JsonParam String name) {
        return "sex="+sex+" age="+age+"name="+name;
    }
}