前言
小程序向 app 转化,发现小程序是
@RequestParam --- from 表单形式
app 里面常用
@RequestBody ---- json 形式
如果在用app 有些接口得重新 写了。所以写一个
SpringBoot一个接口同时支持form表单、form-data、json的优雅写法
开始
效果
1、get 方法用json
2、get 方法form 提交
3、post 方法用json
4、post方法 form 提交
动图
实现方法
开始地方
这个是住 切片吗?之前老说只能做log 日志的方法,今天用上了。
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AppRequestParam {
}
开始配置 里面添加
具体实现
import com.netty.app.annotation.AppRequestParam;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import javax.servlet.ServletRequest;
import java.util.ArrayList;
import java.util.List;
public class RequestMethodProcessor implements HandlerMethodArgumentResolver {
private RequestResponseBodyMethodProcessor jsonResolver;
private ServletModelAttributeMethodProcessor formResolver;
public RequestMethodProcessor() {
List> messageConverters = new ArrayList<>();
RequestMessageConverter RequestMessageConverter = new RequestMessageConverter();
messageConverters.add(RequestMessageConverter);
jsonResolver = new RequestResponseBodyMethodProcessor(messageConverters);
formResolver = new ServletModelAttributeMethodProcessor(true);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
AppRequestParam ann = parameter.getParameterAnnotation(AppRequestParam.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");
}
}
代码是从
这里复制的。。程序员不骗程序员
这里 RequestMessageConverter 是个啥。然后开始了解他了,
看到AbstractNamedValueMethodArgumentResolver 原来接口加密和解密的时候有了解过。
忘记太快了。
全部代码 在下面
public class RequestMessageConverter implements HttpMessageConverter {
@Override
public boolean canRead(Class clazz, MediaType mediaType) {
System.out.println("canRead");
return true;
}
@Override
public boolean canWrite(Class clazz, MediaType mediaType) {
System.out.println("canWrite" + mediaType.getType());
return true;
}
@Override
public List getSupportedMediaTypes() {
System.out.println("getSupportedMediaTypes");
// ArrayList list = Lists.newArrayList();
// list.add(MediaType.parseMediaType(MediaType.APPLICATION_JSON_VALUE));
// list.add(MediaType.parseMediaType(MediaType.MULTIPART_FORM_DATA_VALUE));
/*这样就可以了*/
return Lists.newArrayList();
}
@Override
public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
System.out.println("read");
InputStream body = inputMessage.getBody();
String json = StreamUtils.copyToString(body, Charset.forName("UTF-8"));
return JSONUtil.toBean(json, clazz);
}
@Override
public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
System.out.println("write");
}
}
这个真的可以运行。
@Override
public boolean canRead(Class clazz, MediaType mediaType) {
System.out.println("canRead");
return true;
}
这个有用,没他方法不走。
getSupportedMediaTypes 放回去空就行,在后面已经用if 判断了
read 的是把body 转class 返回去就行了。
感谢
https://mp.weixin.qq.com/s/ElOssSGDo3RUPmsYotsWmA
搜索一堆都是这个,不知道那个是原创了。