欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springmvc @RequestBody String类型参数的使用

程序员文章站 2022-03-04 11:03:32
目录springmvc @requestbody string类型参数springmvc用map接收请求参数分析第一种情况,什么也不设置,无参数传递第二种情况,加个参数试试 => .../tes...

springmvc @requestbody string类型参数

通过如下配置:

   <bean id="mappingjacksonhttpmessageconverter"
          class="org.springframework.http.converter.json.mappingjackson2httpmessageconverter">
        <property name="supportedmediatypes">
            <list>
                <value>text/html;charset=utf-8</value>
                <value>application/json;charset=utf-8</value>
            </list>
        </property>
    </bean>
    <!-- 启动springmvc的注解功能,完成请求和注解pojo的映射 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.requestmappinghandlermapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter">
        <property name="messageconverters">
            <list>
                <ref bean="mappingjacksonhttpmessageconverter"/>
                <!-- json转换器 -->
            </list>
        </property>
    </bean> 

在spring mvc的controller层使用@requestbody接收content-type为application/json的数据时,默认支持map方式和对象方式参数

@requestmapping(value = "/[code]/saveuser", method = requestmethod.post)
    @responsebody
    public jsonresult saveuser(@pathvariable("code") integer code, @requestbody map<string, object> datas,@requestbody user user) {
    。。。
    }

如果是一个参数时也需要用个map或者对象处理,使用string会报解析错误,具体看:abstractjackson2httpmessageconverter的方法read(type type, class

@override
    public object read(type type, class<?> contextclass, httpinputmessage inputmessage)
            throws ioexception, httpmessagenotreadableexception {
        javatype javatype = getjavatype(type, contextclass);
        return readjavatype(javatype, inputmessage);
    }
    private object readjavatype(javatype javatype, httpinputmessage inputmessage) {
        try {
            return this.objectmapper.readvalue(inputmessage.getbody(), javatype);
        }
        catch (ioexception ex) {
            throw new httpmessagenotreadableexception("could not read json: " + ex.getmessage(), ex);
        }
    }

为了让@requestbody支持string参数(目前只支持接收单个参数)

重写org.springframework.http.converter.json.mappingjackson2httpmessageconverter类

package com.test.converter.json
import org.springframework.http.httpinputmessage;
import org.springframework.http.converter.httpmessagenotreadableexception;
import org.springframework.http.converter.json.mappingjackson2httpmessageconverter;
import java.io.ioexception;
import java.lang.reflect.type;
import java.util.linkedhashmap;
/**
 * 处理@requestbody注解为string的情况,只支持接收单个参数的情况
 * created by test
 * date:2017/1/4
 * time:17:33
 */
public class customermappingjackson2httpmessageconverter extends mappingjackson2httpmessageconverter {
    @override
    protected object readinternal(class<?> clazz, httpinputmessage inputmessage) throws ioexception, httpmessagenotreadableexception {
        class<?> desericlazz = getclazz(clazz);
        object param = super.readinternal(desericlazz, inputmessage);
        return gettrueobject(clazz, param);
    }
    @override
    public object read(type type, class<?> contextclass, httpinputmessage inputmessage)
            throws ioexception, httpmessagenotreadableexception {
        type deseritype = gettype(type);
        object param = super.read(deseritype, contextclass, inputmessage);
        return gettrueobject(type, param);
    }
    /**
     * 通过返回参数类型决定是否处理参数,如果是string类型的参数,将解析后的hashmap里的值返回(只支持单个参数)
     *
     * @param type  返回参数类型
     * @param param 参数值
     * @return 实际参数值
     */
    private object gettrueobject(type type, object param) {
        if (type == string.class) {
            object backparam = null;
            if (param != null && param instanceof linkedhashmap) {
                linkedhashmap parammap = (linkedhashmap) param;
                if (parammap.size() == 1) {
                    backparam = parammap.get(parammap.keyset().iterator().next());
                }
            }
            param = backparam;
        }
        return param;
    }
    /**
     * 获取解析参数用的type
     *
     * @param type 参数类型
     * @return
     */
    private type gettype(type type) {
        type desericlazz;
        if (type == string.class) {
            //jackson不支持string默认用linkedhashmap
            desericlazz = linkedhashmap.class;
        } else {
            desericlazz = type;
        }
        return desericlazz;
    }
    /**
     * 获取解析参数用的type
     * @param clazz 参数类型
     * @return
     */
    private class<?> getclazz(class<?> clazz) {
        class<?> desericlazz;
        if (clazz == string.class) {
            //jackson不支持string默认用linkedhashmap
            desericlazz = linkedhashmap.class;
        } else {
            desericlazz = clazz;
        }
        return desericlazz;
    }
}

spring mvc xml配置文件修改:

<bean id="mappingjacksonhttpmessageconverter"
          class="com.test.converter.json.customermappingjackson2httpmessageconverter">
        <property name="supportedmediatypes">
            <list>
                <value>text/html;charset=utf-8</value>
                <value>application/json;charset=utf-8</value>
            </list>
        </property>
    </bean>

controller层:

@requestmapping(value = "/deluser", method = requestmethod.post)
    @responsebody
    public jsonresult deluser(@requestbody string id) {
    。。。
    }

springmvc用map接收请求参数分析

第一种情况,什么也不设置,无参数传递

注解为 @controller @requestmapping

springmvc @RequestBody String类型参数的使用

可以看到传递的为springmvc的bindingawaremodelmap类型,springmvc中的隐含模型就是这个类型,其作用域等价于 request 域,当添加model、modelmap参数时,springmvc实际传入的就是这个隐含模型;向这个隐含模型种设置值后,在返回的页面中就能通过request域取值。

第二种情况,加个参数试试 => .../testmap?test1=2342

结果类型还是一样,且参数不会被传入,当然使用request肯定能取出来。

springmvc @RequestBody String类型参数的使用

第三种情况,给map参数添加@requestparam注解

  

1、get请求 =>http://localhost:8080/ssm/v2/testmap?test1=234234

  

成功传入了参数,注意这个map类型为linkedhashmap,而不是隐含模型了

springmvc @RequestBody String类型参数的使用

  

再添加个model参数看看,隐含模型中依然没有值

  

所以添加@requestparam注解后,springmvc会将 get 请求中封装进对应的参数中,如果参数是map就封装称linkedhashmap而不再传入隐含模型

springmvc @RequestBody String类型参数的使用

2、post请求, 再测试测试post请求

与get的结果一致:参数无@requestparam注解时,map接收隐含模型;添加@requestparam注解时,map接收linkedhashmap;隐含模型中无值。

springmvc @RequestBody String类型参数的使用

第四种情况,给map参数添加@requestbody注解,且请求方式为post

出乎意料的也成功传入了,与@requestparam注解结果类似,也是linkedhashmap

springmvc @RequestBody String类型参数的使用

springmvc @RequestBody String类型参数的使用

复杂点的json数据也能解析接收成功

springmvc @RequestBody String类型参数的使用

springmvc @RequestBody String类型参数的使用

小结一下吧

springmvc处理请求用map类型接收参数时,如果参数无注解,则会传入bindingawaremodelmap类型,等价于model、modelmap参数;

参数添加@requestparam注解时,会将参数包装称linkedhashmap对象,参数的key为map的key,参数值为map的key,支持get、post方法(应该支持put、delete,没有测,俩方法与post类似);

添加@requestbody注解时,接收json类型数据,也会包装成linkedhashmap对象,该注解不支持get请求,get请求没有请求体不能传json。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。