spring mvc 输入输出的一些细节

本文详细介绍了Spring MVC中@RequestParam用于从URL获取参数,@ResponseBody用于返回JSON文档,以及@RequestBody如何将请求参数转化为类对象。讨论了在使用这些注解时可能出现的问题和解决方法,如HTTP状态码400、404和415等,强调了正确配置请求类型和消息转换器的重要性。
摘要由CSDN通过智能技术生成

一:通过@RequestParam 从URL 中获取参数

可以通过@RequestParam获取URL参数

@Controller
public class LoginController {

    @GetMapping(value = "/test1")
    @LogRequired
    public String getUrlData(@RequestParam(value = "keyword1", required = true) String keyword1,
            @RequestParam(value = "keyword2", required = false) String keyword2) {
        System.out.println("keyword1:" + keyword1);
        System.out.println("keyword2:" + keyword2);

        String ret = "keyword1:" + keyword1 + " keyword2:" + keyword2;
        return ret;
    }
}

@RequestParam 指定的某参数的 required 属性为 true时,而访问请求又没有携带该参数,请求会被springmvc自动拦截,返回400错误。如下图:

加上 keyword1=hello 之后,依然报错如下:WhiteLable Error Page  (404)

这是因为默认 springmvc 是会根据函数的返回值,去查找对应的网页资源。

给接口加上 @ResponseBody 后可以解决,注意前端没有给第二个参数时,第二个参数将会是null

@ResponseBody注解可以简单的理解为,把函数的返回值直接返给前端。而不是去找网页资源了。

二:通过 @ResponseBody 返回JSON文档

将函数的返回值类型修改为Object,定义一个Keyword类,代码及结果如下:

@Controller
public class LoginController {

    @ResponseBody
    @GetMapping(value = "/test1")
    @LogRequired
    public Object getUrlData(@RequestParam(value = "keyword1", required = true) String keyword1,
            @RequestParam(value = "keyword2", required = false) String keyword2) {
        System.out.println("keyword1:" + keyword1);
        System.out.println("keyword2:" + keyword2);

        Keyword ret = new Keyword();
        ret.keyword1 = keyword1;
        ret.keyword2 = keyword2;
        return ret;
    }

    static class Keyword {
        public String keyword1;

        public String keyword2;

        public String getKeyword1() {
            return keyword1;
        }

        public void setKeyword1(String keyword1) {
            this.keyword1 = keyword1;
        }

        public String getKeyword2() {
            return keyword2;
        }

        public void setKeyword2(String keyword2) {
            this.keyword2 = keyword2;
        }
    }
}

三:通过@RequestBody 自动将请求参数转化为类对象


    @ResponseBody
    @GetMapping(value = "/test1")
    @LogRequired
    public Object getUrlData(@RequestBody Keyword keyword) {
        System.out.println("keyword1:" + keyword.keyword1);
        System.out.println("keyword2:" + keyword.keyword2);

        Keyword ret = keyword;
        return ret;
    }

运行后,报错如下:org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

@RequestBody 会尝试从请求的正文中获取数据,而不像@RequestParam那样会尝试从URL中获取。

因此,我们需要把@GetMapping 修改为 @PostMapping ,同时前端改成 Post 提交数据:

尝试运行,报错如下:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

改尝试使用 Junit 来构建一个 post 请求:

    @Test
    public void test() throws Exception {

        mMockMvc.perform(
                MockMvcRequestBuilders
                        .post("/test1").param("keyword1", "hello1").param("keyword2", "hello2")
                        .contentType("application/json"))
                .andExpect(MockMvcResultMatchers.status().is(200))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }

很遗憾,还是不行,报错如下:

org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.Object com.test.controllers.LoginController.getUrlData(com.test.controllers.LoginController$Keyword)

post的参数不可以是 key value 键值对,必须是 json 文档,另外使用 content 方法,而不是 param 方法,修改代码如下:

    @Test
    public void test() throws Exception {

        Keyword k = new Keyword();
        k.setKeyword1("hi");
        k.setKeyword2("hello");
        String json = new ObjectMapper().writeValueAsString(k);

        mMockMvc.perform(
                MockMvcRequestBuilders
                        .post("/test1").content(json)
                        .contentType("application/json"))
                .andExpect(MockMvcResultMatchers.status().is(200))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }


小结(摘至Spring Action 中文第四版)

@ResponseBody 注解会告知Spring,我们要将返回的对象作为资源发送给客户羰,并将其转换为客户端可接受的表达形式。更具体的讲,DispatcherServlet 将会考虑到请求中的Accept头部信息,并查找能在够为客户端提供所需表述形式的消息转换器。

举例来讲,假设客户端的Accept头部信息表明它接受 application/json.... (省略若干 字) 消息转换器会将 Controller 返回的 类转换为JSON文档。

@RequestBody 告诉 Spring 查找一个消息转换器,将来自客户 端的资源表述转换为对象。

@使用@RestController 代替 @Controller,Spring 将会为该控制器的所有处理方法应用消息转换功能。

(注意:@RestController 是 @Contoller + @ResponseBody ,但是不包括   @RequestBody )

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zonson9999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值