发送空字符串作为RequestBody不会到达其余端点

时间:2018-10-12 03:47:28

标签: java spring-boot request jackson

我正在尝试为端点编写一个unitTest。

此终结点应遵循以下json对象

@PostMapping(value = "/test")
public String endPoint(@RequestBody String obj) {

        try {
          JSONObject inputJsonObject = new JSONObject(individualJson);
        } catch (JSONException | IOException e) {
                    throw new MyException("JSONObject not valid");
        }
 ......
 }

在单元测试中,我试图发送一个空字符串,并且希望具有JSONException

mvc.perform(post(url)
                .contentType(MediaType.APPLICATION_JSON)
                .content(""))
                .andReturn().getResponse();

但是我的帖子没有碰到我的端点...这就像它无法将空字符串评估为String:“”没碰到端点 “”(带有空格)正击中端点...

以下是调用返回的异常:

  

org.springframework.http.converter.HttpMessageNotReadableException:   缺少所需的请求正文:公开   com.ba.mypackage.MyController.endPoint(java.lang.String)

如何通过传递空字符串“”来访问端点?

3 个答案:

答案 0 :(得分:1)

您不能这样做,因为发送空字符串作为正文与在这种情况下不发送正文是一样的事情,并且@RequestBody注释不允许不发送正文,因为其{{ 1}}属性为required

将空字符串作为正文发送与不发送正文相同,因为在HTTP中,POST请求的标头部分和正文部分用CRLF分隔,并且在具有正文和不具有正文时都需要分隔CRLF 。这是HTTP规范中定义的方式,有关详细信息,请参见https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html

  

5个请求

     

从客户端到服务器的请求消息在该消息的第一行中包括要应用于资源的方法,资源的标识符以及所使用的协议版本。

true

您提供的标头部分,正文是您想要具有的空字符串。但是,无论如何,您都需要有CRLF,因此请求看起来像这样:

    Request       = Request-Line              ; Section 5.1
                    *(( general-header        ; Section 4.5
                     | request-header         ; Section 5.3
                     | entity-header ) CRLF)  ; Section 7.1
                    CRLF
                    [ message-body ]          ; Section 4.3

或者将[CRLF]放在该字符所在的位置,

POST /url HTTP/1.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, application/javascript, text/javascript
Content-Length: 0
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_112)
Accept-Encoding: gzip,deflate
 

由于content-length为零,并且CRLF分隔符必须始终存在,所以您如何区分以正文形式发送的空字符串和根本没有正文发送的字符串之间的区别?事情是你做不到,在这种情况下,这是同一件事,所以你的要求无法完成。

答案 1 :(得分:0)

因为空字符串不是有效的字符串,因此与Null相似。

但是,如果您只是想点击控制器,而不对控制器内部的空字符串值感兴趣,只需将参数标记为可选。

public String endPoint(@RequestBody(required = false) String obj) {

答案 2 :(得分:-1)

我可以建议两种传递空字符串的方法。

  1. 最好将空字符串分配给最终变量,如下所述。

    private static final String YOUR_STRING = "";
    
  2. 您还可以使用StringBuffer传递空字符串。