前言小程序向 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)@Documentedpublic @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 搜索一堆都是这个,不知道那个是原创了。 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |