8.

【Spring】@Controllerアノテーションとは

編集
この記事の要点
  • @ControllerSpring MVC のコントローラクラスを表すアノテーション
  • HTML View を返す Web ページ向け(戻り値は View 名)
  • JSON API を返したい場合は @RestController (= @Controller + @ResponseBody)
  • メソッドに @RequestMapping / @GetMapping 等を組み合わせて URL を紐付け
  • 機能的には @Component と同じ Bean 登録 + Spring MVC ハンドラとして認識

 

@Controller の基本

@Controller
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public String list(Model model) {
        List users = userService.findAll();
        model.addAttribute("users", users);
        return "users/list";  // ← View 名 (users/list.html or .jsp)
    }

    @GetMapping("/{id}")
    public String show(@PathVariable Long id, Model model) {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "users/show";
    }

    @GetMapping("/create")
    public String createForm(Model model) {
        model.addAttribute("user", new UserCreateForm());
        return "users/create";
    }

    @PostMapping
    public String create(@ModelAttribute @Valid UserCreateForm form, BindingResult result) {
        if (result.hasErrors()) {
            return "users/create";  // バリデーション失敗
        }
        User user = userService.createUser(form.getName(), form.getEmail());
        return "redirect:/users/" + user.getId();
    }
}

@Controller vs @RestController

項目@Controller@RestController
用途HTML / JSP View 返却JSON / XML API
戻り値View 名 (String)POJO → JSON 自動変換
@ResponseBody個別メソッドに付けるクラス全体に暗黙適用
典型例サーバサイドレンダリングSPA バックエンド / 外部 API

View 名の解決

@GetMapping("/users/{id}")
public String show(@PathVariable Long id, Model model) {
    model.addAttribute("user", userService.findById(id));
    return "users/show";
    // ↓ ViewResolver が以下を探す
    // - templates/users/show.html (Thymeleaf)
    // - WEB-INF/jsp/users/show.jsp (JSP)
    // - 等
}

// プレフィックス
return "redirect:/users";              // → 302 redirect
return "forward:/api/internal";        // → 内部 forward (同 request)
return "users/show";                    // → 通常 view 解決

Model / ModelAndView

// Model 引数で受け取る (推奨)
@GetMapping("/users/{id}")
public String show(@PathVariable Long id, Model model) {
    model.addAttribute("user", userService.findById(id));
    model.addAttribute("title", "ユーザー詳細");
    return "users/show";
}

// ModelAndView 返却
@GetMapping("/users/{id}")
public ModelAndView showMav(@PathVariable Long id) {
    ModelAndView mav = new ModelAndView("users/show");
    mav.addObject("user", userService.findById(id));
    return mav;
}

// Map 引数 (簡略形)
@GetMapping("/users/{id}")
public String showMap(@PathVariable Long id, Map model) {
    model.put("user", userService.findById(id));
    return "users/show";
}

フォーム受け取り

// フォーム DTO
public class UserCreateForm {
    @NotBlank(message = "名前は必須です")
    @Size(max = 100)
    private String name;

    @NotBlank
    @Email
    private String email;
    // getter/setter
}

// 表示
@GetMapping("/users/create")
public String createForm(Model model) {
    model.addAttribute("form", new UserCreateForm());
    return "users/create";
}

// 受信 + バリデーション
@PostMapping("/users")
public String create(@ModelAttribute("form") @Valid UserCreateForm form,
                     BindingResult result,
                     RedirectAttributes redirect) {
    if (result.hasErrors()) {
        return "users/create";  // フォームに戻る (エラー表示)
    }
    User user = userService.createUser(form.getName(), form.getEmail());
    redirect.addFlashAttribute("message", "ユーザーを作成しました");
    return "redirect:/users/" + user.getId();
}

HTML テンプレート (Thymeleaf)





    タイトル


    

名前

メール

編集

例外ハンドリング

@Controller
public class UserController {

    @ExceptionHandler(EntityNotFoundException.class)
    public String handleNotFound(EntityNotFoundException ex, Model model) {
        model.addAttribute("error", ex.getMessage());
        return "errors/404";
    }

    @ExceptionHandler(BusinessException.class)
    public String handleBusiness(BusinessException ex, RedirectAttributes redirect) {
        redirect.addFlashAttribute("error", ex.getMessage());
        return "redirect:/users";
    }
}

// グローバル
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String handleAll(Exception ex, Model model) {
        model.addAttribute("error", "システムエラー");
        return "errors/500";
    }
}

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. @After
  2. @Autowired
  3. @Bean
  4. @Before
  5. @Column
  6. @Component
  7. @Configuration
  8. @Controller
  9. @Data
  10. @Entity
  11. @GeneratedValue
  12. @Id
  13. @Modifying
  14. @PathVariable
  15. @PropertySource
  16. @Repository
  17. @RequestBody
  18. @RequestMapping
  19. @ResponseBody
  20. @RestController
  21. @Service
  22. @SpringBootApplication
  23. @Table
  24. @Transactional
  25. @Value