簡體   English   中英

Spring 4 RestController:沒有從PUT請求接收數據

[英]Spring 4 RestController: not receiving data from PUT request

我正在嘗試使用Spring構建一個非常基本的REST API。

我的URL端點是:

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"
    }
}

更新請求對於PUTPOST請求我發送相同的測試數據:

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 {

}

我不知道為什么這不起作用?

這是Servlet規范的限制以及Spring用於填充模型屬性的內部工作方式。

首先,規范說

3.1.1參數可用時

以下是在將表單數據填充到參數集之前必須滿足的條件:

  1. 該請求是HTTP或HTTPS請求。
  2. HTTP方法是POST。
  3. 內容類型是application / x-www-form-urlencoded。
  4. servlet對請求對象上的任何getParameter系列進行了初始調用。 如果不滿足條件且后表單數據未包含在參數集中,則后續數據仍必須通過請求對象的輸入流對servlet可用。 如果滿足條件,則表單數據將不再可用於直接從請求對象的輸入流中讀取。

其次,你的處理程序方法的第二個參數,類型為Note的一個,實際上被認為是一個模型屬性 ,就好像它是用@ModelAttribute隱式注釋的一樣。 因此,它由Spring的ModelAttributeMethodProcessor HandlerMethodArgumentResolver使用getParameter (及其方法系列)填充創建的實例的字段。

由於這是PUT請求,因此無法通過getParameter檢索參數。 但是,仍然可以通過請求體訪問它們,但是Spring並不是為了模型屬性而去那里。

您可以自己進行轉換。 但我建議您將請求內容更改為JSON或XML for PUT,並使用@RequestBody注釋參數。


長期以來一直要求為PUT請求添加參數。

不知道在這里是否屬於這種情況(或者如果它現在甚至是相關的,還沒有使用REST的東西一段時間),但我在過去遇到了一個問題,Jetty和Tomcat處理PUT請求的方式不同(應用程序本身就像你的代碼一樣使用Spring MVC),另一個期望參數在URL中,另一個想要它們在體內,就像POST一樣。

顯然,HTTP規范在這方面並不十分精確,因此不同的容器可以以不同的方式處理它。 更多信息在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM