В чем разница между аннотациями @Controller и @RestController в Spring?

Ответ

Обе аннотации отмечают класс как компонент, обрабатывающий HTTP-запросы, но предназначены для разных архитектурных стилей.

Аспект @Controller @RestController
Назначение Часть паттерна MVC (Model-View-Controller). Для создания RESTful веб-сервисов (API).
Возвращаемое значение Имя представления (view), например, "home.html". Данные (объект), которые сериализуются в JSON/XML и отправляются в теле HTTP-ответа.
Аннотации по умолчанию Только @Controller. @Controller + @ResponseBody на уровне класса.
Типичный Content-Type text/html (для рендеринга HTML). application/json.

Пример @Controller (MVC с представлением):

@Controller
public class WebController {
    @GetMapping("/greeting")
    public String greeting(Model model) {
        model.addAttribute("name", "World");
        return "greeting"; // Имя шаблона (greeting.html)
    }

    @GetMapping("/api/old")
    @ResponseBody // Без этого вернется строка как имя шаблона
    public String getData() {
        return "Data";
    }
}

Пример @RestController (REST API):

@RestController
@RequestMapping("/api/users")
public class UserApiController {
    @GetMapping
    public List<User> getAllUsers() {
        // Автоматически конвертируется в JSON
        return userService.findAll();
    }

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User saved = userService.save(user);
        return ResponseEntity.created(URI.create("/api/users/" + saved.getId())).body(saved);
    }
}

Вывод: Используйте @Controller для server-side рендеринга HTML, а @RestController — для построения JSON/XML API.

Ответ 18+ 🔞

А, ну вот, опять эти ваши аннотации, блядь. Смотри, тут два чувака, вроде похожи, а на деле — пиздец какая разница, как между молотком и микроскопом. Один для старых добрых HTML-страниц, другой — для этих ваших модных APIшек, которые JSONами плюются.

Штука @Controller @RestController
Зачем он вообще? Это классика, детка, MVC. Тот самый дед, который шаблоны рендерит. Это уже для REST API, чтобы с фронтендами или мобилками общаться данными, а не HTML-версткой.
Что возвращает? Имя файла шаблона, типа "hello.html". Spring потом сам найдёт этот файл и отрендерит. Сами данные — объект, список, что угодно. Spring автоматом превратит это в JSON или XML и в ответ сунет.
Что в нём по умолчанию? Просто @Controller. Всё. Это, сука, комбо-пакет! @Controller + @ResponseBody сразу на весь класс. Удобно, блядь.
Что в заголовке ответа? Обычно text/html, потому что HTMLшку шлёт. application/json — король современных API.

Вот смотри, как @Controller работает (старая школа):

@Controller
public class WebController {
    @GetMapping("/greeting")
    public String greeting(Model model) {
        model.addAttribute("name", "World");
        return "greeting"; // Имя шаблона (greeting.html)
    }

    @GetMapping("/api/old")
    @ResponseBody // Без этого вернется строка как имя шаблона
    public String getData() {
        return "Data";
    }
}

Видишь? Без @ResponseBody он будет искать шаблон с именем "Data", а это, ёпта, пиздец. С ним — просто строку в ответ шлёт.

А вот @RestController — это уже другое кино (REST API):

@RestController
@RequestMapping("/api/users")
public class UserApiController {
    @GetMapping
    public List<User> getAllUsers() {
        // Автоматически конвертируется в JSON
        return userService.findAll();
    }

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User saved = userService.save(user);
        return ResponseEntity.created(URI.create("/api/users/" + saved.getId())).body(saved);
    }
}

Вот тут уже ни о каких шаблонах речи нет. Вернул список юзеров — получи на выходе чистый JSON, ебать его в сраку. Удобно для аяксов, мобилок и прочей нечисти.

Итог, блядь, простой: Хочешь странички на сервере генерить — бери @Controller. Делаешь API, которое JSONами трется — твой выбор @RestController, и нехуй тут думать. Всё, вопрос закрыт, в рот меня чих-пых.