Spring 4 RestController:没有从PUT请求接收数据

时间:2015-03-12 18:29:31

标签: java spring rest spring-mvc

我正在尝试使用Spring构建一个非常基本的REST API。

我的网址端点是:

GET    /notes
GET    /notes/{noteId}
POST   /notes
PUT    /notes/{noteId}
DELETE /notes/{noteId}

除了我想要运行以更新项目的PUT请求之外,所有这些端点都可以正常工作。

问题是没有通过PUT接收数据,因为它适用于POST

这是我的控制者;我通过添加与update方法相同但使用POST的方法对其进行了测试,但效果很好。我不知道为什么?

package notes;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/notes")
public class NotesController {

    ...

    @RequestMapping(value="/{noteId}", method=RequestMethod.PUT)
    public Response update(@PathVariable Integer noteId, Note note) {

        return new Response("Note Updated", note);

    }

    @RequestMapping(value="/{noteId}", method=RequestMethod.POST)
    public Response updateWithPost(@PathVariable Integer noteId, Note note) {

        return new Response("Note Updated", note);

    }

    ...

}

使用邮递员,我已对POST http://127.0.0.1:8080/notes/5进行了测试,回复是:

{
    "message": "Note Updated",
    "note": {
        "id": null,
        "title": "Hello World detail content",
        "text": "Hello World",
        "createdAt": "72, Mar 2015",
        "updatedAt": "72, Mar 2015"
    }
}

但对于具有完全相同数据的PUT http://127.0.0.1:8080/notes/5,响应为:

{
    "message": "Note Updated",
    "note": {
        "id": null,
        "title": "",
        "text": "",
        "createdAt": "72, Mar 2015",
        "updatedAt": "72, Mar 2015"
    }
}

更新请求 适用于PUT和{ POST请求我发送相同的测试数据:

title: Hello World
text: Hello World detail content

响应级

package notes;

public class Response {

    private String message;
    private Note note;

    public Response(String text) {
        setMessage(text);
    }

    public Response(String text, Note note) {
        setMessage(text);
        setNote(note);
    }

    //...getters/setters
}

注意课程

package notes;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Note {

    private Integer id = null;
    private String title = "";
    private String text = "";
    private Date createdAt = new Date();
    private Date updatedAt = new Date();

    public Note() {}

    public Note(String title, String text) {
        this.setTitle(title);
        this.setText(text);
    }


    //...getters/setters
}

ApplicationConfig

package notes;

import org.springframework.context.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@EnableWebMvc
@Configuration
public class ApplicationConfig {

}

我不知道为什么这不起作用?

2 个答案:

答案 0 :(得分:4)

这是Servlet Spec的限制以及Spring用于填充模型属性的内部工作方式。

首先,规范说

  

3.1.1参数可用时

     

以下是在将表单数据填充到表单之前必须满足的条件   参数集:

     
      
  1. 请求是HTTP或HTTPS请求。
  2.   
  3. HTTP方法是POST。
  4.   
  5. 内容类型为application / x-www-form-urlencoded。
  6.   
  7. servlet已对请求对象上的任何getParameter方法系列进行了初始调用。如果不符合条件   并且帖子表单数据不包含在参数集中   数据必须仍然可以通过请求对象对servlet可用   输入流。如果满足条件,则不再发布表单数据   可以直接从请求对象的输入中读取   流。
  8.   

其次,你的处理程序方法的第二个参数,即类型Note的参数,实际上是considered a model attribute,好像它是用@ModelAttribute隐式注释的。因此,它由Spring的ModelAttributeMethodProcessor处理。此HandlerMethodArgumentResolver使用getParameter(及其系列方法)填充已创建实例的字段。

由于这是PUT请求,因此无法通过getParameter检索参数。但是,它们仍然可以通过请求体访问,但是Spring并不是为了模型属性而去那里。

您可以自己进行转换。但我建议您将请求内容更改为JSON或XML for PUT,并使用@RequestBody带注释的参数。


There is a long standing request to add parameters for PUT requests.

答案 1 :(得分:0)

不知道这里是否属实(或者如果它现在甚至是相关的,还没有使用REST的东西一段时间),但我已经打了一个过去Jetty和Tomcat处理PUT的问题 - 请求不同(应用程序本身就像你的代码一样使用Spring MVC),另一个期望参数在URL中,另一个想要它们在体内,喜欢POST。

显然,HTTP规范在这方面并不十分精确,因此不同的容器可以以不同的方式处理它。更多信息here