代码之家  ›  专栏  ›  技术社区  ›  Mohamed Taboubi

以requestbody的形式发送空字符串,但不到达rest端点

  •  1
  • Mohamed Taboubi  · 技术社区  · 6 年前

    我试图为端点编写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();
    

    然而,这篇文章并不是我的终点…它好像无法计算空字符串作为字符串:“”但未命中终结点 “”正在命中终结点…

    以下是调用返回的异常:

    org.springframework.http.converter.httpMessageTableException:异常 缺少必需的请求正文:public com.ba.mypackage.mycontroller.endpoint(java.lang.string)

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

    3 回复  |  直到 6 年前
        1
  •  1
  •   eis    6 年前

    不能,因为将空字符串作为body发送与不在此上下文中发送body是同一回事,并且不允许发送body @RequestBody 注释,因为它的默认值 required 属性是 true 是的。

    将空字符串作为body发送与不发送body是一样的,因为在http中,post请求有一个由crlf分隔的header部分和body部分,在有body和没有body的情况下都需要分隔crlf。这就是在http规范中定义它的方式,请参见 https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html 有关详细信息:

    5请求

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

        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
     
    

    或者,把[crlf]放在那个角色的位置上,

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

    由于内容长度为零,并且crlf分隔符必须始终存在,您如何区分作为body发送的空字符串和根本不发送body的空字符串?问题是你做不到,在这种情况下这是一样的,所以你的要求是做不到的。

        2
  •  0
  •   Amit Phaltankar    6 年前

    因为空字符串不是有效字符串,并且处理方式类似于空字符串。

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

    public String endPoint(@RequestBody(required = false) String obj) {
    
        3
  •  -2
  •   Angela Amarapala    6 年前

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

    1. 最好将空字符串赋给下面提到的最终变量。

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