There is a lot of code on the web that is generic CVS. Believe me, if you read this article carefully, you will be able to fully grasp this point. This article is not suitable for CVS directly, be sure to understand it first.
The PHP interface is compatible with both POST JSON and form forms, and even form-data is compatible with the PHP interface. Because PHP requests are written with lax receiver code. See more here.
In Java, an interface supports only one Content-Type. Json uses @requestBody, form uses @requestParam or no writing, and form-data uses MultipartFile.
Compatible versions
If you want to incorporate all three in one interface, the clumsy approach is to get HttpServletRequest and then write your own method parsing. Similar to the following:
private Map<String, Object> getParams(HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType.contains("application/json")) {
// json parsing...
return null;
} else if (contentType.contains("application/x-www-form-urlencoded")) {
// form parsing...
return null;
} else if (contentType.contains("multipart")) {
// File stream parsing
return null;
} else {
throw new BizException("Unsupported Content-Type"); }}Copy the code
But there’s a downside to this
- The code is ugly, and the parsing code is stinky and long
- You can only return the fixed map or reassemble the parameter classes yourself
- Can’t use
@Valid
Checking parameters, like I have to check dozens of parameters is a disaster
Elegant version
There are forms and JSON compatible versions on the Internet, but not form-data compatible versions. Here I add something.
1. Custom annotations
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GamePHP {
}
Copy the code
2. Custom annotation parsing
public class GamePHPMethodProcessor implements HandlerMethodArgumentResolver {
private GameFormMethodArgumentResolver formResolver;
private GameJsonMethodArgumentResolver jsonResolver;
public GamePHPMethodProcessor(a) { List<HttpMessageConverter<? >> 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 not supported");
}
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 not supported"); }}Copy the code
3. Add it to Spring Configuration
@Bean
public MyMvcConfigurer mvcConfigurer(a) {
return new MyMvcConfigurer();
}
public static class MyMvcConfigurer implements WebMvcConfigurer {
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(newGamePHPMethodProcessor()); }}Copy the code
4. Special processing of form-data
The introduction of the jar package
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Copy the code
New Parse bean
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver(a){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
resolver.setResolveLazily(true);The resolveLazily property is enabled to defer file parsing in order to catch file size exceptions in UploadAction
resolver.setMaxInMemorySize(40960);
resolver.setMaxUploadSize(50*1024*1024);// Upload file size 50M 50 x 1024 x 1024
return resolver;
}
Copy the code
Special instructions, GameJsonMethodArgumentResolver and GameFormMethodArgumentResolver is our custom json and analytical form, if you don’t have a custom, Using spring default ServletModelAttributeMethodProcessor and RequestResponseBodyMethodProcessor can also.
Simply change the @RequestParam annotation to @gamephp and the interface is compatible with all three Content-Types at once.
When Spring starts, MyMvcConfigurer calls addArgumentResolvers to inject GamePHPMethodProcessor. The supportsParameter method determines whether to use the resolver. If true, the resolveArgument method is used.
At this point we can conclude that PHP is the most garbage language in the world. Writing code, maintaining a crematorium.