import java.lang.annotation.*; 自定义注解 /** * 该注解用于绑定请求参数(JSON字符串) * * @author Zhang Kaitao */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestJsonParam { /** * 用于绑定的请求参数名字 */ String value() default ""; /** * 是否必须,默认是 */ boolean required() default true; }
JavaBean
public class TestParam { private Integer id; private String name; }
Controller
@ResponseBody @RequestMapping(value="testParam", method= RequestMethod.POST) public Response testParam(@RequestJsonParam("data") TestParam testParam){ return Response.success(testParam); }
自定义参数解析器
package com.yllt.yezhi.application.config.mvc.resolver.jsonparam.impl; /** * 解析请求参数json字符串 * * @author yaozq * @editer LOpSSH */ public class RequestJsonParamMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver implements WebArgumentResolver { private class RequestJsonParamNamedValueInfo extends NamedValueInfo { private RequestJsonParamNamedValueInfo() { super("", false, null); } private RequestJsonParamNamedValueInfo(RequestJsonParam annotation) { super(annotation.value(), annotation.required(), null); } } public RequestJsonParamMethodArgumentResolver() { super(null); } public boolean supportsParameter(MethodParameter parameter) { /** * 判断是否是需要我们解析的参数类型 */ if (parameter.hasParameterAnnotation(RequestJsonParam.class)) { return true; } return false; } @Override protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) { RequestJsonParam annotation = parameter.getParameterAnnotation(RequestJsonParam.class); return new RequestJsonParamNamedValueInfo(annotation); } /** * 真正解析的方法 */ @Override protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception { String[] paramValues = webRequest.getParameterValues(name); Class<?> paramType = parameter.getParameterType(); if (paramValues == null) { return null; } try { if (paramValues.length == 1) { Type type = parameter.getGenericParameterType(); if (MapWapper.class.isAssignableFrom(paramType)) { MapWapper<?, ?> jsonMap = (MapWapper<?, ?>) paramType.newInstance(); MapType mapType = (MapType) getJavaType(HashMap.class); if (type instanceof ParameterizedType) { mapType = (MapType) mapType.withKeyType(getJavaType((Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0])); mapType = (MapType) mapType.withContentType(getJavaType((Class<?>) ((ParameterizedType) type).getActualTypeArguments()[1])); } jsonMap.setInnerMap(JSONMapper.INSTANCE.<Map>readValue(paramValues[0], mapType)); return jsonMap; } JavaType javaType = getJavaType(paramType); if (Collection.class.isAssignableFrom(paramType)) { javaType = javaType.withContentType(getJavaType((Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0])); } // return JSONMapper.INSTANCE.readValue(text, paramType); return JsonUtil.fromJson(paramValues[0], paramType); } } catch (Exception e) { throw new JsonMappingException("Could not read request json parameter", e); } throw new UnsupportedOperationException( "too many request json parameter '" + name + "' for method parameter type [" + paramType + "], only support one json parameter"); } protected JavaType getJavaType(Class<?> clazz) { return TypeFactory.defaultInstance().constructFromCanonical(clazz.getCanonicalName()); } @Override protected void handleMissingValue(String paramName, MethodParameter parameter) throws ServletException { String paramType = parameter.getParameterType().getName(); throw new ServletRequestBindingException( "Missing request json parameter '" + paramName + "' for method parameter type [" + paramType + "]"); } /** * spring 3.1之前 */ @Override public Object resolveArgument(MethodParameter parameter, NativeWebRequest request) throws Exception { if (!supportsParameter(parameter)) { return WebArgumentResolver.UNRESOLVED; } return resolveArgument(parameter, null, request, null); } }
SpringBoot自定义基于注解的参数解析器
@Configuration public class MvcConfig implements WebMvcConfigurer { //springmvc的配置 @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new RequestJsonParamMethodArgumentResolver()); //添加自定义参数解析器 } @Override public void configurePathMatch(PathMatchConfigurer configurer) { } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { } @Override public void configureAsyncSupport(AsyncSupportConfigurer configurer) { } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { } @Override public void addFormatters(FormatterRegistry registry) { } // @Bean // public TestMvcInterceptor testMvcInterceptor(){ // return new TestMvcInterceptor(); // } @Bean public AccessTimeLimitInterceptor accessTimeLimitInterceptor(){ return new AccessTimeLimitInterceptor(); } @Bean public AuthorityInterceptor authorityInterceptor(){ return new AuthorityInterceptor(); } /** * 添加自定义拦截器配置 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { // registry.addInterceptor(accessTimeLimitInterceptor()).addPathPatterns("/**").excludePathPatterns("/shanmi/shanMi/chongZhiPrint");; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { } @Override public void addCorsMappings(CorsRegistry registry) { } @Override public void addViewControllers(ViewControllerRegistry registry) { } @Override public void configureViewResolvers(ViewResolverRegistry registry) { } @Override public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) { } //接口返回格式设置 @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.removeIf(it -> it instanceof MappingJackson2HttpMessageConverter); //设置日期格式 ObjectMapper objectMapper = new ObjectMapper(); SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); objectMapper.setDateFormat(smt); //设置中文编码格式 List<MediaType> list = new ArrayList<MediaType>(); list.add(MediaType.APPLICATION_JSON); list.add(MediaType.APPLICATION_JSON_UTF8); // converters.clear(); MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper); mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper); mappingJackson2HttpMessageConverter.setSupportedMediaTypes(list); //5.将convert添加到converters当中. converters.add(mappingJackson2HttpMessageConverter); } @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { } @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { resolvers.add(new ExceptionHandler()); } @Override public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { }