見出し画像

[Java&SpringBoot] いろいろアノテーションとResponseEntity


1.はじめに

こんにちは、今日はSpringBootで使ってるコントローラのアノテーションを簡単に整理してみました。 よく使うけど、毎回混乱して明確に覚えておく必要がありそうです。

リクエストとレスポンスがそれぞれjson形式かどうかによってエラーが出ることがあるので、正確なアノテーションを引数で指定してデータを渡す必要があります。Postmanというプログラムを使って色んなテストをしてみます。


2.いろいろアノテーション

@RestController = @Controller + @ResponseBody

Studentクラスを生成してフィールド、コンストラクタ、ゲッターとセッターを設定します。

    // http://localhost:8080/students
    @GetMapping("students")
    public List<Student> getStudents() {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"Ramesh","Fadatare"));
        students.add(new Student(2, "umesh", "Fadatare"));
        students.add(new Student(3,"Ram","Jadhav"));
        students.add(new Student(4,"Sanjay", "Pawar"));
        return students;
    }


    // Spring BOOT REst APi with Path variable
    // {id} - URL template variable
    // http://localhost:8080/students/1
    @GetMapping("students/{id}")
    public Student studentPathVariable(@PathVariable int studentId) {
        return new Student(studentId, "Ramesh", "Fadatare");
    }
}

@PathVariable
メソッドの引数をURIテンプレート変数の値にバインドするために使用します。


// Spring boot REST API with Request Param
    // http://localhost:8080/students?id=1&firstName=Ramesh&lastName=Fadatare
    @GetMapping("students/query")
    public Student studentRequestVariable(@RequestParam int id,
                                          @RequestParam String firstName,
                                          @RequestParam String lastName){
        return new Student(id, firstName, lastName);
    }


@RequestParam
リクエストのクエリーパラメーターの値を抽出するためのものです。

    // Spring boot REST API trhat handles HTTP POST Request
    // @PostMapping and @RequestBody

    @PostMapping("students/create")
    @ResponseStatus(HttpStatus.CREATED)
    public Student createStudent(@RequestBody Student student) {
        System.out.println(student.getId());
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return student;
    }


@PostMapping
HTTP POST メソッドのリクエストを処理するメソッドであることを示す役割をします。HTTP POSTはサーバーにデータを送信して新しいリソースを生成したり、処理するために使われるメソッドです。

@RequestBody

リクエストからJSONオブジェクトを取得し、そのJSONオブジェクトをJavaオブジェクトに自動的に変換します。

内部的には、spring が提供する HTTP メッセージコンバータを使って JSON を Java オブジェクトに変換します。

@ResponseStatus

レスポンスに HTTP ステータスを送信するには、 アノテーションを使用します。


    // Spring boot Rest APi that handles Http put request - updating existing resource
    @PutMapping("students/{id}/update")
    public Student updatetudent(@RequestBody Student student, @PathVariable("id") int studentId) {
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return student;
    }

@PutMapping
HTTP PUT メソッドのリクエストを処理するメソッドであることを示す役割をします。HTTP PUTはサーバーのデータを更新したり修正するために使われるメソッドです。

// Spring boot rest api that handles http delete request - deleting the existing resource
    @DeleteMapping("students/{id}/delete")
    public String deleteStudent(@PathVariable("id") int studentId) {
        System.out.println(studentId);
        return "Student deleted successfully";
    }


@DeleteMapping

HTTP DELETE メソッドのリクエストを処理するメソッドであることを示す役割をします。HTTP DELETEはサーバーで特定のリソースを削除するために使われるメソッドです。


3.ResponseEntity

    @GetMapping("student")
    public ResponseEntity<Student> getStudent(){
        Student student = new Student(
          1,
          "Ramesh",
          "Fadatare"
        );
        //return new ResponseEntity<>(student, HttpStatus.OK);
        return ResponseEntity.ok()
                .header("custom-header","hi~man")
                .body(student);
    }

ResponseEntity
Spring Frameworkで提供するクラスで、HTTP応答の状態コード、ヘッダや本文を制御する方法を提供します。 上記のメソッドを見ると、戻りタイプとreturn部分にResponseEntityコードが書いてあるのが見えます。

「ok()」は応答のステータスコードを明示的に設定することができます。 ok()メソッドは200 OKステータスコードを設定します。
応答本文にオブジェクトを含めることができ、そのオブジェクトは自動的にJSON形式に変換されます。

上記のメソッドはResponseEntity<Student>を返し、ステータスコードHttpStatus.OKと一緒にStudentオブジェクトを応答本文に含めて返します。この場合、応答本文はJSON形式でStudentオブジェクトが含まれます。

ResponseEntityを使わない場合も多いです。 この場合、単純にStudentオブジェクトを返し、Springはこの返しオブジェクトをJSONに変換して応答します。 (Spring Bootの基本動作)

しかし、特別な状況でHTTPステータスコードやヘッダなどを細かく調整することが難しいという問題があります。

なぜResponseEntityを使うのか分かったので、今まで作った全てのコントローラの戻りタイプをResponseEntityに変えてみましょう。

@RestController
public class StudentController {

    // http://localhost:8080/student
    @GetMapping("student")
    public ResponseEntity<Student> getStudent(){
        Student student = new Student(
          1,
          "Ramesh",
          "Fadatare"
        );
        //return new ResponseEntity<>(student, HttpStatus.OK);
        return ResponseEntity.ok()
                .header("custom-header","hi~man")
                .body(student);
    }

    // http://localhost:8080/students
    @GetMapping("students")
    public ResponseEntity<List<Student>> getStudents(){
        List<Student> students = new ArrayList<>();
        students.add(new Student(1, "Ramesh", "Fadatare"));
        students.add(new Student(2, "umesh", "Fadatare"));
        students.add(new Student(3, "Ram", "Jadhav"));
        students.add(new Student(4, "Sanjay", "Pawar"));
        return ResponseEntity.ok(students);
    }

    // Spring BOOT REST API with Path Variable
    // {id} - URI template variable
    // http://localhost:8080/students/1/ramesh/fadatare
    @GetMapping("students/{id}/{first-name}/{last-name}")
    public ResponseEntity<Student> studentPathVariable(@PathVariable("id") int studentId,
                                       @PathVariable("first-name") String firstName,
                                       @PathVariable("last-name") String lastName){
        Student student = new Student(studentId, firstName, lastName);
        return ResponseEntity.ok(student);
    }

    // Spring boot REST API with Request Param
    //  http://localhost:8080/students/query?id=1&firstName=Ramesh&lastName=Fadatare
    @GetMapping("students/query")
    public ResponseEntity<Student> studentRequestVariable(@RequestParam int id,
                                          @RequestParam String firstName,
                                          @RequestParam String lastName){
        Student student = new Student(id, firstName, lastName);
        return ResponseEntity.ok(student);
    }

    // Spring boot REST API trhat handles HTTP POST Request
    // @PostMapping and @RequestBody
    @PostMapping("students/create")
    //@ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<Student> createStudent(@RequestBody Student student) {
        System.out.println(student.getId());
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return new ResponseEntity<>(student, HttpStatus.CREATED);
    }

    // Spring boot Rest APi that handles Http put request - updating existing resource
    @PutMapping("students/{id}/update")
    public ResponseEntity<Student> updatetudent(@RequestBody Student student, @PathVariable("id") int studentId) {
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return ResponseEntity.ok(student);
    }

    // Spring boot rest api that handles http delete request - deleting the existing resource
    @DeleteMapping("students/{id}/delete")
    public ResponseEntity<String> deleteStudent(@PathVariable("id") int studentId) {
        System.out.println(studentId);
        return ResponseEntity.ok("Student deleted successfully");
    }
}



4.@RequestMapping

package net.javaguides.springboot.controller;

import net.javaguides.springboot.bean.Student;
import org.apache.coyote.Response;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("students")
public class StudentController {

    // http://localhost:8080/student
    @GetMapping("student")
    public ResponseEntity<Student> getStudent(){
        Student student = new Student(
          1,
          "Ramesh",
          "Fadatare"
        );
        //return new ResponseEntity<>(student, HttpStatus.OK);
        return ResponseEntity.ok()
                .header("custom-header","hi~man")
                .body(student);
    }

    // http://localhost:8080/students
    @GetMapping//("students")
    public ResponseEntity<List<Student>> getStudents(){
        List<Student> students = new ArrayList<>();
        students.add(new Student(1, "Ramesh", "Fadatare"));
        students.add(new Student(2, "umesh", "Fadatare"));
        students.add(new Student(3, "Ram", "Jadhav"));
        students.add(new Student(4, "Sanjay", "Pawar"));
        return ResponseEntity.ok(students);
    }

    // Spring BOOT REST API with Path Variable
    // {id} - URI template variable
    // http://localhost:8080/students/1/ramesh/fadatare
    //@GetMapping("students/{id}/{first-name}/{last-name}")
    @GetMapping("{id}/{first-name}/{last-name}")
    public ResponseEntity<Student> studentPathVariable(@PathVariable("id") int studentId,
                                       @PathVariable("first-name") String firstName,
                                       @PathVariable("last-name") String lastName){
        Student student = new Student(studentId, firstName, lastName);
        return ResponseEntity.ok(student);
    }

    // Spring boot REST API with Request Param
    //  http://localhost:8080/students/query?id=1&firstName=Ramesh&lastName=Fadatare
    //@GetMapping("students/query")
    @GetMapping("query")
    public ResponseEntity<Student> studentRequestVariable(@RequestParam int id,
                                          @RequestParam String firstName,
                                          @RequestParam String lastName){
        Student student = new Student(id, firstName, lastName);
        return ResponseEntity.ok(student);
    }

    // Spring boot REST API trhat handles HTTP POST Request
    // @PostMapping and @RequestBody
    //@PostMapping("students/create")
    @PostMapping("create")
    //@ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<Student> createStudent(@RequestBody Student student) {
        System.out.println(student.getId());
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return new ResponseEntity<>(student, HttpStatus.CREATED);
    }

    // Spring boot Rest APi that handles Http put request - updating existing resource
    //@PutMapping("students/{id}/update")
    @PutMapping("{id}/update")
    public ResponseEntity<Student> updatetudent(@RequestBody Student student, @PathVariable("id") int studentId) {
        System.out.println(student.getFirstName());
        System.out.println(student.getLastName());
        return ResponseEntity.ok(student);
    }

    // Spring boot rest api that handles http delete request - deleting the existing resource
    @DeleteMapping("students/{id}/delete")
    public ResponseEntity<String> deleteStudent(@PathVariable("id") int studentId) {
        System.out.println(studentId);
        return ResponseEntity.ok("Student deleted successfully");
    }
}

最後にもう一つアノテーションを紹介したいと思います。

これは@RequestMappingですが、私はこのアノテーションを最初に知らなかった時、各コントローラーのエンドポイント通りにブラウザにリクエストを出し続けて無駄なことをしたことがあります。馬鹿みたいに何時間も無駄にしました。 www
簡単に言うと、このアノテーションの役割は、共通するエンドポイントをまとめて、他のコントローラーから比較的簡単にエンドポイントを入力できるように整理する役割です。


5.まとめ


8月1ヶ月間機能追加をしながら過去に作成したコントローラの全てのアノテーションをちゃんと知っていたとは思えなかったし、特にResponseEntityが他の例題コードにあったので大きな考えなしに持ってきて使ってました。 しかし、今日の勉強をきっかけにアノテーションを全体的に整理して、ResponseEntityを使う理由をより明確に知ることができて今後の開発に大きな助けになりそうです。



エンジニアファーストの会社 株式会社CRE-CO
ソンさん


この記事が気に入ったらサポートをしてみませんか?