小程序开发|小程序制作|小程序开发网

搜索

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

2022-8-10 18:51| 发布者: 北极圈的瓜| 查看: 535| 评论: 1

摘要: 前言小程序向 app 转化,发现小程序是@RequestParam --- from 表单形式app 里面常用@RequestBody ---- json 形式如果在用app 有些接口得重新 写了。所以写一个SpringBoot一个接口同时支持form表单、form-data、jso

前言

小程序向 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
搜索一堆都是这个,不知道那个是原创了。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

鲜花

握手

雷人

路过

鸡蛋
发表评论

最新评论

引用 北极圈的瓜 2023-10-11 11:44
赞,这是我看到最牛的文章了,详细的不能再详细了,感谢楼主!

查看全部评论(1)

返回顶部