@RequestBody และคำอธิบายประกอบ @ResponseBody ใน Spring


139

ใครสามารถอธิบาย@RequestBodyและ@ResponseBodyบันทึกย่อใน Spring 3 ได้ไหม สิ่งที่พวกเขาสำหรับ? ตัวอย่างใด ๆ ก็จะดี

คำตอบ:


219

มีส่วนทั้งในเอกสารที่เรียกว่า16.3.3.4 แมปร่างกายคำขอกับคำอธิบายประกอบ และเป็นหนึ่งเรียกว่า16.3.3.5 การทำแผนที่การตอบสนองของร่างกายที่มีคำอธิบายประกอบ ฉันขอแนะนำให้คุณศึกษาหัวข้อเหล่านั้น ที่เกี่ยวข้องเพิ่มเติม: @RequestBodyjavadocs, @ResponseBodyjavadocs

ตัวอย่างการใช้งานจะเป็นดังนี้:

ใช้ JavaScript-library เช่น JQuery คุณจะโพสต์ JSON-Object เช่นนี้:

{ "firstName" : "Elmer", "lastName" : "Fudd" }

วิธีการควบคุมของคุณจะมีลักษณะเช่นนี้:

// controller
@ResponseBody @RequestMapping("/description")
public Description getDescription(@RequestBody UserStats stats){
    return new Description(stats.getFirstName() + " " + stats.getLastname() + " hates wacky wabbits");
}

// domain / value objects
public class UserStats{
    private String firstName;
    private String lastName;
    // + getters, setters
}
public class Description{
    private String description;
    // + getters, setters, constructor
}

ตอนนี้ถ้าคุณมีแจ็คสันบน classpath ของคุณ (และมีการ<mvc:annotation-driven>ตั้งค่า) สปริงจะแปลง JSON ขาเข้าเป็นวัตถุ UserStats จากโพสต์เนื้อความ (เพราะคุณเพิ่ม@RequestBodyคำอธิบายประกอบ) และมันจะทำให้วัตถุที่ส่งคืนเป็น JSON เป็นลำดับ@ResponseBodyคำอธิบายประกอบ) ดังนั้นเบราว์เซอร์ / ไคลเอ็นต์จะเห็นผลลัพธ์ JSON นี้:

{ "description" : "Elmer Fudd hates wacky wabbits" }

ดูคำตอบก่อนหน้านี้ของฉันสำหรับตัวอย่างการทำงานที่สมบูรณ์: https://stackoverflow.com/a/5908632/342852

หมายเหตุ: RequestBody / ResponseBody แน่นอนว่าไม่ จำกัด JSON ซึ่งทั้งคู่สามารถจัดการได้หลายรูปแบบรวมถึงข้อความธรรมดาและ XML แต่ JSON อาจเป็นรูปแบบที่ใช้มากที่สุด


ปรับปรุง

ตั้งแต่ Spring 4.x คุณมักจะไม่ใช้@ResponseBodyในระดับวิธี แต่จะใช้@RestControllerในระดับชั้นเรียนโดยมีเอฟเฟกต์แบบเดียวกัน

นี่คือข้อความจากเอกสารอย่างเป็นทางการของSpring MVC :

@RestControllerเป็นคำอธิบายประกอบประกอบด้วยว่าเป็นตัวเองMeta-ข้อเขียน ด้วย@Controllerและ@ResponseBodyเพื่อระบุตัวควบคุมที่มีทุกวิธีสืบทอดประเภทระดับ@ResponseBodyคำอธิบายประกอบและจึงเขียนโดยตรงกับร่างกายตอบสนองกับความละเอียดของการแสดงผลและมุมมองที่มีแม่แบบ HTML


ในคำตอบที่เชื่อมโยงของคุณคุณใช้@ResponseBodyคำอธิบายประกอบกับพารามิเตอร์ไม่ใช่วิธีการ ฉันพบข้อผิดพลาดในการลองใช้วิธีการดังนั้นฉันจึงคิดว่าคำตอบอื่น ๆ ของคุณนั้นถูกต้อง ฉันคิดว่าคุณควรมีgetDescription(@RequestBody UserStats stats)ข้างต้น
Patrick

3
@ Patrick no, @RequestBodyอยู่ในพารามิเตอร์, @ResponseBodyเป็นวิธีการ ความแตกต่างที่สำคัญ!
ฌอนแพทริคฟลอยด์

1
@SeanPatrickFloyd ขออภัยฉันไม่ได้ตั้งใจพูดถึง@ResponseBodyเลย อย่างที่คุณเพิ่งบอก@RequestBodyไปพารามิเตอร์ใช่มั้ย แต่ในคำตอบข้างต้นคุณมีมันในวิธีการ
แพทริค

1
@SeanPatrickFloyd @RequestBodyเป็นจริงต้องยังคงเป็นนัยเมื่อใช้@ResponseBody @RestControllerกรุณาแก้ไขคำตอบของคุณมันมี upvotes มากเกินไปที่จะเป็นเท็จ!
Sumit Jain

@SumitJain ยุติธรรม: คำตอบนี้อยู่ก่อน@RestControllerแล้วและเปลี่ยนไปเมื่อมีการนำมาใช้
Sean Patrick Floyd

32

@RequestBody : คำอธิบายประกอบที่ระบุว่าพารามิเตอร์ method ควรจะถูกผูกไว้กับเนื้อความของคำขอ HTTP

ตัวอย่างเช่น:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
    writer.write(body);
}

สามารถใส่คำอธิบายประกอบ @ResponseBodyบนเมธอดและระบุว่าชนิดการส่งคืนควรถูกเขียนไปยังเนื้อความการตอบกลับ HTTP โดยตรง (และไม่ได้อยู่ในโมเดลหรือตีความเป็นชื่อมุมมอง)

ตัวอย่างเช่น:

@RequestMapping(path = "/something", method = RequestMethod.PUT)
public  @ResponseBody String helloWorld() {
    return "Hello World";
}  

หรือเราสามารถใช้คำอธิบายประกอบ@RestControllerแทนการ@Controllerเพิ่มความคิดเห็น @ResponseBodyนี้จะลบจำเป็นที่จะต้องใช้

สำหรับรายละเอียดเพิ่มเติม


5

ด้านล่างเป็นตัวอย่างของวิธีการในตัวควบคุม Java

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public HttpStatus something(@RequestBody MyModel myModel) 
{
    return HttpStatus.OK;
}

โดยการใช้คำอธิบายประกอบ @RequestBody คุณจะได้รับค่าของคุณแมปกับรุ่นที่คุณสร้างขึ้นในระบบของคุณสำหรับการจัดการการโทรเฉพาะใด ๆ ในขณะที่ใช้ @ResponseBody คุณสามารถส่งอะไรกลับไปยังสถานที่ที่มีการสร้างคำขอ ทั้งสองสิ่งจะถูกแมปอย่างง่ายดายโดยไม่ต้องเขียนโปรแกรมวิเคราะห์คำที่กำหนดเองใด ๆ


1
package com.programmingfree.springshop.controller;

import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.programmingfree.springshop.dao.UserShop;
import com.programmingfree.springshop.domain.User;


@RestController
@RequestMapping("/shop/user")
public class SpringShopController {

 UserShop userShop=new UserShop();

 @RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
 public User getUser(@PathVariable int id) {
  User user=userShop.getUserById(id);
  return user;
 }


 @RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
 public List<User> getAllUsers() {
  List<User> users=userShop.getAllUsers();
  return users;
 }


}

ในตัวอย่างข้างต้นพวกเขาจะแสดงรายละเอียดผู้ใช้และรหัสเฉพาะตอนนี้ฉันต้องการใช้ทั้ง id และชื่อ

1) localhost: 8093 / plejson / ร้านค้า / ผู้ใช้ <--- ลิงค์นี้จะแสดงรายละเอียดผู้ใช้ทั้งหมด
2) localhost: 8093 / plejson / shop / user / 11 <---- ถ้าฉันใช้ 11 ในลิงค์หมายความว่ามันจะ แสดงรายละเอียดเฉพาะผู้ใช้ 11 คน

ตอนนี้ฉันต้องการใช้ทั้ง id และชื่อ

localhost: 8093 / plejson / shop / user / 11 / raju <----------------- แบบนี้มันหมายความว่าเราสามารถใช้อันใดอันหนึ่งในนี้ได้โปรดช่วยฉันด้วย .... .


โปรดแก้ไขการจัดรูปแบบของคำตอบและตัวอย่างโค้ด
Maciej Lach

โปรดอธิบายว่ารหัสนี้ช่วยผู้ถามได้อย่างไร ขอบคุณ.
Leonid Glanz

programming-free.com/2014/03/… .................... ผ่านลิงค์นี้คุณจะได้รับ ... ขอบคุณ
user5409646

programming-free.com/2014/03/… ....................................... .................................................. ..... ผ่านลิงค์นี้คุณจะได้รับขอบคุณ
user5409646
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.