千家信息网

怎么使用@RequestBody传递多个不同对象方式

发表于:2024-10-22 作者:千家信息网编辑
千家信息网最后更新 2024年10月22日,本篇内容主要讲解"怎么使用@RequestBody传递多个不同对象方式",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么使用@RequestBody传递多
千家信息网最后更新 2024年10月22日怎么使用@RequestBody传递多个不同对象方式

本篇内容主要讲解"怎么使用@RequestBody传递多个不同对象方式",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么使用@RequestBody传递多个不同对象方式"吧!

目录
  • @RequestBody传递多个不同对象

    • 解决方案1

    • 解决方案2

  • 使用多个@RequestBody接收参数

    • 原因

    • 解决办法:两个类,直接copy即可

@RequestBody传递多个不同对象

如果使用spring mvc同客户端通信,完全使用json数据格式,需要增加RequestBody注解,函数参数为自定义类

@Controllerpublic class TestController{  @RequestMapping("\test")  @ResponseBody  public RetureResult test(@RequestBody User user){    return new ReturnResult();  }  }

这样的话,可以将接收到的json格式的数据转换为指定的数据对象user。比如{name:"test"},name为User类的属性域。通过ResponseBody注解,可以返回json格式的数据。

有时接收json格式数据时,我们可能需要将其转换为多个对象。

以下方式是错误的。原因是request的content-body是以流的形式进行读取的,读取完一次后,便无法再次读取了。

@Controllerpublic class TestController{  @RequestMapping("\test")  @ResponseBody  public RetureResult test(@RequestBody User user,@RequestBody Address address){    return new ReturnResult();  }  }

解决方案1

增加一个包装类,将所需要类写入,增加get,set方法

@Controllerpublic class TestController{  @RequestMapping("\test")  @ResponseBody  public RetureResult test(@RequestBody Param param){    User user=param.getUser();    Address address=param.getAddress();    return new ReturnResult();  }  }class Param{     private User user;    private Address address;       public User getUser() {        return user;    }     public void setUser(User user) {        this.user = user;    }     public Address getAddress() {        return address;    }     public void setAddress(Address address) {        this.address = address;    }}

此时传输的json数据格式变为{user:{name:"test"},address:{location:"新华路"}}。

由于只是在TestController中增加一个包装类,不会影响其他的类以及已经定义好的model类,因此可以非常方便的达到接收多个对象参数的目的。

解决方案2

将接收参数定义为Map,然后使用map转object工具,转换成需要的对象。

此时,即使自定义的Param类中的属性即使比json数据中的属性少了,也没关系。

其中JSONUtils为自定义的工具类,可使用常见的fastjson等工具包包装实现。

@Controllerpublic class TestController{  @RequestMapping("\test")  @ResponseBody  public Object test(@RequestBody Map models){   User user=JsonXMLUtils.map2object((Map)models.get("user"),User.class);    Address address=JsonXMLUtils.map2object((Map)models.get("address"),Address.class);    return models;  }}import com.alibaba.fastjson.JSON; public class JsonXMLUtils {    public static String obj2json(Object obj) throws Exception {        return JSON.toJSONString(obj);    }     public static  T json2obj(String jsonStr, Class clazz) throws Exception {        return JSON.parseObject(jsonStr, clazz);    }     public static  Map json2map(String jsonStr)     throws Exception {            return JSON.parseObject(jsonStr, Map.class);    }      public static  T map2obj(Map map, Class clazz) throws Exception {        return JSON.parseObject(JSON.toJSONString(map), clazz);    }}

使用多个@RequestBody接收参数

原因

常规情况下,因为request的body只能读取一次,@RequestBody也只能解析一次,这就导致解析第二个的@RequestBody的时候stream已经关闭了,无法再次读取。

话不多说,上货:

解决办法:两个类,直接copy即可

import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.*; public class BodyReaderRequestWrapper extends HttpServletRequestWrapper {    private final String body;     /**     *     * @param request     */    public BodyReaderRequestWrapper(HttpServletRequest request) throws IOException{        super(request);        StringBuilder sb = new StringBuilder();        InputStream ins = request.getInputStream();        BufferedReader isr = null;        try{            if(ins != null){                isr = new BufferedReader(new InputStreamReader(ins));                char[] charBuffer = new char[128];                int readCount = 0;                while((readCount = isr.read(charBuffer)) != -1){                    sb.append(charBuffer,0,readCount);                }            }else{                sb.append("");            }        }catch (IOException e){            throw e;        }finally {            if(isr != null) {                isr.close();            }        }         sb.toString();        body = sb.toString();    }     @Override    public BufferedReader getReader() throws IOException {        return new BufferedReader(new InputStreamReader(this.getInputStream()));    }     @Override    public ServletInputStream getInputStream() throws IOException {        final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());        ServletInputStream servletIns = new ServletInputStream() {            @Override            public boolean isFinished() {                return false;            }             @Override            public boolean isReady() {                return false;            }             @Override            public void setReadListener(ReadListener readListener) {             }             @Override            public int read() throws IOException {                return byteArrayIns.read();            }        };        return  servletIns;    }}
import org.springframework.stereotype.Component; import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException; @Component@WebFilter(filterName = "crownFilter", urlPatterns = "/*")public class BodyReaderRequestFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {     }     @Override    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest)req;        HttpServletResponse response = (HttpServletResponse)res;        BodyReaderRequestWrapper requestWrapper  = new BodyReaderRequestWrapper(request);        if(requestWrapper == null){            filterChain.doFilter(request,response);        }else {            filterChain.doFilter(requestWrapper,response);        }    }     @Override    public void destroy() {     }}

使用:自行测试。

到此,相信大家对"怎么使用@RequestBody传递多个不同对象方式"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0