SpringBoot 同一个接口同时支持 form 表单、form-data、json 的优雅写法

}

}

复制代码

但是这样写有弊端

  1. 代码很丑,具体到解析代码又臭又长

  2. 只能返回固定 map 或者自己重新组装参数类

  3. 无法使用 @Valid 校验参数,像我这种几十个参数都要检验的简直是灾难

优雅版本


网上有 form 表单和 json 同时兼容的版本,但是没有兼容 form-data,我在这做一下补充。

1. 自定义注解

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface GamePHP {

}

复制代码

2. 自定义注解解析

public class GamePHPMethodProcessor implements HandlerMethodArgumentResolver {

private GameFormMethodArgumentResolver formResolver;

private GameJsonMethodArgumentResolver jsonResolver;

public GamePHPMethodProcessor() {

List> messageConverters = new ArrayList<>();

PHPMessageConverter PHPMessageConverter = new PHPMessageConverter();

messageConverters.add(PHPMessageConverter);

jsonResolver = new GameJsonMethodArgumentResolver(messageConverters);

formResolver = new GameFormMethodArgumentResolver();

}

@Override

public boolean supportsParameter(MethodParameter parameter) {

GamePHP ann = parameter.getParameterAnnotation(GamePHP.class);

return (ann != null);

}

@Override

public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {

ServletRequest servletRequest = nativeWebRequest.getNativeRequest(ServletRequest.class);

String contentType = servletRequest.getContentType();

if (contentType == null) {

throw new IllegalArgumentException(“不支持contentType”);

}

if (contentType.contains(“application/json”)) {

return jsonResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);

}

if (contentType.contains(“application/x-www-form-urlencoded”)) {

return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);

}

if (contentType.contains(“multipart”)) {

return formResolver.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);

}

throw new IllegalArgumentException(“不支持contentType”);

}

}

复制代码

3. 添加到 spring configuration

@Bean

public MyMvcConfigurer mvcConfigurer() {

return new MyMvcConfigurer();

}

public static class MyMvcConfigurer implements WebMvcConfigurer {

public void addArgumentResolvers(List resolvers) {

resolvers.add(new GamePHPMethodProcessor());

}

}

复制代码

4. form-data 的特殊处理

引入 jar 包

commons-fileupload

commons-fileupload

1.3.1

commons-io

commons-io

2.4

复制代码

新增解析 bean

@Bean(name = “multipartResolver”)

public MultipartResolver multipartResolver(){

CommonsMultipartResolver resolver = new CommonsMultipartResolver();

resolver.setDefaultEncoding(“UTF-8”);

resolver.setResolveLazily(true);//resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常

resolver.setMaxInMemorySize(40960);

resolver.setMaxUploadSize(5010241024);//上传文件大小 50M 5010241024

return resolver;

}

复制代码

你可能感兴趣的:(spring,boot,json,python)