Выбрать главу

Обрабатывать HTTP-запросы GET, для пути запроса /design

Составьте список ингредиентов

Обработать запрос и данные по ингредиентам на основе шаблона для отображения как HTML и отправить в веб-браузер.

Следующий класс DesignTacoController отвечает этим требованиям

Листинг 2.2 Начальный класс Spring контроллера

package tacos.web;

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.validation.Errors;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import lombok.extern.slf4j.Slf4j;

import tacos.Taco;

import tacos.Ingredient;

import tacos.Ingredient.Type;

@Slf4j

@Controller

@RequestMapping("/design")

public class DesignTacoController {

   @GetMapping

   public String showDesignForm(Model model) {

      List<Ingredient> ingredients = Arrays.asList(

         new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),

         new Ingredient("COTO", "Corn Tortilla", Type.WRAP),

         new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),

         new Ingredient("CARN", "Carnitas", Type.PROTEIN),

         new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),

         new Ingredient("LETC", "Lettuce", Type.VEGGIES),

         new Ingredient("CHED", "Cheddar", Type.CHEESE),

         new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),

         new Ingredient("SLSA", "Salsa", Type.SAUCE),

         new Ingredient("SRCR", "Sour Cream", Type.SAUCE)

      );

      Type[] types = Ingredient.Type.values();

      for (Type type : types) {

         model.addAttribute(type.toString().toLowerCase(),

         filterByType(ingredients, type));

      }

      model.addAttribute("design", new Taco());

      return "design";

   }

}

Первое, что следует отметить об DesignTacoController, - это набор аннотаций, применяемых на уровне класса. Первый, @Slf4j, является аннотацией, предоставляемой Lombok, которая во время выполнения автоматически генерирует SLF4J (Simple Logging Facade for Java, https://www.slf4j.org/) Logger в классе. Эта скромная аннотация имеет тот же эффект, что и при явном добавлении следующих строк в класс:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DesignTacoController.class);

Вы будете использовать этот Logger немного позже.

Следующая аннотация, примененная к DesignTacoController это - @Controller. Эта аннотация служит, чтобы идентифицировать этот класс как контроллер и пометить его как кандидата на компонентное сканирование, так, чтобы Spring обнаружил его и автоматически создал экземпляр DesignTacoController как bean в контексте приложения Spring.

DesignTacoController аннотирован @RequestMapping. @RequestMapping аннотация, используемая на уровне класса, определяет тип запросов, обрабатываемых этим контроллером. В этом случае он указывает, что контроллер DesignTacoController будет обрабатывать запросы, путь к которым начинается с /design.

ОБРАБОТКА ЗАПРОСА GET

@GetMapping - относительно новая аннотация, появившаяся в Spring 4.3. До Spring 4.3 вы, возможно, использовали аннотацию @RequestMapping уровня метода вместо:

@RequestMapping(method=RequestMethod.GET)

Очевидно, что @GetMapping более сжатый и конкретный метод HTTP. @GetMapping является лишь одним членом семьи request-mapping аннотации. В таблице 2.1 перечислены все аннотации request-mapping, доступные в Spring MVC.

Таблица 2.1 Spring MVC request-mapping аннотации

Аннотации

Описание

@RequestMapping

обработка запросов общего назначения

@GetMapping

обрабатывает запросы HTTP GET

@PostMapping

обрабатывает запросы HTTP POST

@PutMapping

обрабатывает запросы HTTP PUT

@DeleteMapping

обрабатывает HTTP-запросы на удаление

@Pathmapping

обрабатывае HTTP-запросов на патч

 

Делайте правильные вещи легкими

Всегда рекомендуется быть как можно более конкретным при объявлении сопоставлений запросов в методах контроллера. По крайней мере, это означает объявление как пути (или наследование пути от класса уровня @RequestMapping), так и метода HTTP, который он будет обрабатывать.

Длинный @RequestMapping((method=RequestMethod.GET) сделал заманчивым взять ленивый выход и оставить атрибут метода. Благодаря новым аннотациям отображения Spring 4.3, правильная вещь также является легкой - с меньшим количеством ввода.

Новые аннотации request-mapping имеют те же атрибуты, что и @RequestMapping, поэтому их можно использовать везде, где пришлось бы использовать @RequestMapping.

Как правило, я предпочитаю использовать только @RequestMapping на уровне класса, чтобы указать базовый путь. Я использую более конкретные @GetMapping, @PostMapping и т. д. Для каждого из методов обработчика.

Теперь, когда вы знаете, что метод showDesignForm() будет обрабатывать запрос, давайте посмотрим на тело метода, чтобы увидеть, как он устроен. Основное - это то что метод создает список объектов Ingredient. Список пока жестко закодирован. Когда мы к этому вернемся в главе 3, вы получите список доступных ингредиентов тако из базы данных