初学者がアノテーションと戦う(SpringBoot)

# はじめに
Javaの学習を1か月ほど行った後、
1週間ほど前からSpringBootの勉強を始めました。

だがしかし、どうにもSpringBootがわからん。

アノテーションっていっぱい種類あるんだなぁ・・・。

この記事でまとめて覚える。

# アノテーションって何者？
「@RestController」など「@」から始まる記述。
ここに記述している内容はここで使うものだよ～っていうのを明示する方法。

例えばクラスのまえに「@Controller」とつけると、そのクラスはControllerとして読み込まれる。
「@RequestParam("/api")」とつけるとURLに応じた処理を記述することができる。

そのように、機能を簡単にまとめることができる方法。

簡単に・・・・・・・？

初学者の自分の所感は複雑だなぁ・・・という印象。
おそらくこの「簡単に」というのは初学者が理解しやすいという意味ではなく
アノテーションがなければもっと複雑な記述になってしまうが、
アノテーションを用いることでわかりやすくするという意味。

<font color="red">なので、アノテーションならではの、作法や記述方法をしっかりとおさえることが大前提。</font>
つまり書き方がわからないとアノテーションも意味が分からない。

コードを読み解く際に「どういう意味？これはJavaがわからない？SpringBootがわからない？」
それを防ぐためには1つ1つ噛み砕いていく必要がある。

この記事では、初学者の自分がアノテーションを自分なりに考えてまとめて
わかることを増やしていこうという目的で記録していく。


# アノテーションを詳しく見ていく

### @RestController @Controller
MVCモデルのC部分(コントローラー部分)であることを示すアノテーション
アプリを実行する際にはこちらが読まれて、ViewやModelを動かす。

`@RestController`と`@Controller`の違いはデータの受け方、返し方にある。
`@RestController`はResponseBodyに返す。Jsonやxmlを返す場合に使う
`@Controller`でJsonやxmlを返したい場合にはメソッドに`@ResponseBody`をつける必要がある。

`@ResponseBody`を付けずにJsonやxmlを返したい場合に使うのが`@RestController`。

つまり、REST APIを構築するうえでデータ返却をする際にJson形式などの統一を図る際に
`@RestController`を使用するという認識でOK！（REST APIの統一インターフェイスに該当する部分）

▼参考にしたサイト

https://note.com/yota7/n/n2ee5c62957f5

https://qiita.com/YAKINIKU/items/abaa54ba531a30850d10

https://tech.012grp.co.jp/entry/rest_api_basics

### @ControllerAdvice
Controllerの補助的な役割をするクラスにつけるアノテーション。

エラー処理(@ExceptionHandler)などの例外処理を記述しておくことができるイメージ。
Controller内に`@ExceptionHandler`を定義し、例外処理を記述することも可能ではあるが
このように`@ControllerAdvice`を利用し、別クラスで定義するのが一般的らしい。

製品開発となると、複数人での開発が前提となるので可能な限り複数人での開発ができるように
機能ごとにクラスを分けるという機能を果たす側面もあると思う。

▼参考にしたサイト

https://olafnosuke.hatenablog.com/entry/2022/06/26/202904

### @RequestMapping
URLに応じた処理を記述するアノテーション。`@RequestMapping("/aaa")`と記述するのが基本。
`(/aaa)`はURLの末尾。つまりローカル環境であれば`http://localhost:8080/aaa`の処理を指す。

メソッドを指定しない場合のHTTPメソッドのデフォルト値は<font color="red">「GET」</font>

`@RequestMapping(path = "/input", method = POST)`のようにメソッドを指定するとHTTPメソッドが指定したものに変わる。
本例は`method=POST`となっているのでPOSTメソッドとして処理される。

```java:@RequestMapping記述例１
@RequestMapping(value="/success")
public String index() {
	return"アクセス成功です";
}
//http://localhost:8080/successで「アクセス成功です」が返り値として返る
```

```java:@RequestMapping記述例２
@RestController
@RequestMapping("/test")
public class practice_controller {

    @RequestMapping(value="/success")
    public String index() {
    	return"アクセス成功です";
    }
    
}
//クラス全体に「/test」、indexメソッドに「/success」を付与
//http://localhost:8080/test/successで「アクセス成功です」が返り値として返る
```

`@GetMapping`,`@PostMapping`,`@PutMapping`,`@DeleteMapping`など
HTTPメソッドを含めたアノテーションも存在する。

▼参考にしたサイト

https://www.shookuro.com/entry/2016/08/21/134349

https://b1san-blog.com/post/spring/spring-controller/

### @RequestParam
値を取得するアノテーションの種類の1つ
値を取得するアノテーションは`@PathVariable`などいろいろあるがそのうちのひとつ。

`http://localhost:8080/test?param=aaa`のようにURLに含まれる`?param=`から値を取得する。

```java:@RequestParam記述例1
//http://localhost:8080/test?param=あいうえお
//URLの「?param=あいうえお」部分を受け取れる
@RequestMapping("/test")
private String testRequestParam( @RequestParam String param ) {
    return "受け取ったパラメーター：" + param;
}
//「受け取ったパラメーター：あいうえお」と返り値を返す。
```

```java:@RequestParam記述例2
//http://localhost:8080/test?param=あいうえお&num=111
//URLの「?param=あいうえお&num=111」部分を受け取れる
@RequestMapping("/test")
private String testRequestParam( @RequestParam String param , @RequestParam String num ) {
    return "受け取ったパラメーター：" + param + num;
}
//「受け取ったパラメーター：あいうえお111」と返り値を返す。
```

ただ、@RequestParamだと1つ1つパラメーターを定義しないといけないの手間だよね。

`private String testRequestParam( @RequestParam String param , @RequestParam String num ) `
これ、2個だからそこまで長くないけど

`private String testRequestParam( @RequestParam String param , @RequestParam String num , @RequestParam int id , @RequestParam String text)` 
4つの変数を登録するだけでこの長さ。見るだけで読みたくない・・・。煩雑。

というので、クラスに変数を前もって登録しておく方法がDTOという方式。
<font color="red">注意：コントローラー内に記述するのではなく、扱うデータ種を別クラスで定義するってこと。</font>

DTOクラスはデータを転送するためのクラス。
DAOクラスと実行用クラスの間にあるイメージのクラス。

<font color="red">実行クラスからModelに対してHTTPメソッドを実施する場合にはDTOクラスに対して行う
DTOクラスがモデルとの橋渡しになる。</font>

```java:DTOクラス
public class SampleDataParam{
String id;
String firstName;
String lastName;
int age;

public SampleDataParam(){
  }
}

//各変数にgeterとsetterも必要！！！！！！！！！！！！！！！！！！
```


▼参考にしたサイト

https://kanda-it-school-kensyu.com/java-jdbc-contents/jj_ch04/jj_0402/

https://confrage.jp/spring-boot%E3%81%AErestcontroller%E3%81%AEpathvariable%E3%81%A8requestparam%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/#toc3

https://qiita.com/takahirocook/items/fa1822f2f22c3786593e

https://qiita.com/takasek/items/70ab5a61756ee620aee6

https://architecting.hateblo.jp/entry/2021/05/24/104812

https://www.youtube.com/watch?v=Ey2gbUUP-RA

### @ModelAttribute
DTOの値に対して、HTTPメソッドのGETメソッドを実行したい際に`@ModelAttribute`を引数につける。
Attributeは「～のせいにする」という意味。Modelとのつながりを発生させるという理解でOK。

```java:@ModelAttribute記述例
@GetMapping
    public SampleData get(@ModelAttribute SampleDataParam param) {
        //...
}
```


### @RequestBody
HTTPメソッドのPOSTメソッドなどのでデータを追加や編集をする際に使う。
```java:@RequestBody記述例
@PostMapping
public void create(@RequestBody SampleDataParam param) {
    //...
}
```

### @PathValiable
URLからパラメーターを受け取るアノテーションの1つ。
似たアノテーションに`@RequestParam`がある。

`http://localhost:8080/test/5`の`/5`部分をパラメーターとして受け取れる。

```java:
//http://localhost:8080/test/5
//@Pathvariableは「/5」みたいな情報をURLから情報を取得する

@RequestMapping("/test/{param}")
private String testPathVariable( @PathVariable String param ) {
    return "受け取ったパラメータ：" + param;
}

//「受け取ったパラメータ：5」と返り値を返す。
```

# Lombokって便利なライブラリがあるらしい

形式的に書かないといけない「冗長コード」を削減するためのもの。

冗長コードを削減・・・？どういうこっちゃ・・・？

<font color="red">めっちゃ簡単に言うと、使えるアノテーションが増える！！！！</font>ってこと。
いろいろあるが自身が便利だと感じたアノテーションを記述していくことにする。

▼参考にしたサイト

https://qiita.com/opengl-8080/items/671ffd4bf84fe5e32557

https://youtu.be/TYdFPcqWtyo?feature=shared

### @Getter @Setter
本来メンバー変数に対してアクションを起こすときは
getterメソッドとsetterメソッドで、メンバー変数への道を作っておく必要があるが
それらを省略することができるアノテーション。

こ、これは便利やでぇ・・・。

GetterとSetterって見た目めちゃぐちゃぐちゃになるし、わかりにくいって思ってた。

```java:@Getter/@Setterの記述例
package sample.lombok;

import lombok.Getter;
import lombok.Setter;

public class Main {

    public static void main(String... args) {
        Main m = new Main();
        
        m.setValue("Hello @Getter, @Setter");
        System.out.println(m.getValue());
    }
    
    @Getter @Setter
    private String value;
}

//メンバー変数の上に書く
```

### @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor
メンバー変数への値の代入するコンストラクタの作成を省略させてくれるもの。
詳しくは別記事にまとめたのでそちらを参照

https://qiita.com/suke_qiita/items/ebad13a57ed69daf03a0#%E4%BD%99%E8%AB%87springboot%E3%81%A7%E3%81%AF%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%82%92%E7%B0%A1%E5%8D%98%E3%81%AB%E3%81%A7%E3%81%8D%E3%82%8B


# 随時更新