Вступление
Если вы читали что-нибудь о Spring , разработали
проект или даже хотя бы отдаленно интересовались, как это работает, вы
познакомились с аннотацией @RequestMapping
Это одна из основных аннотаций в Spring, которая сопоставляет HTTP-запросы (URL-адреса) с методами:
@RequestMapping("/")
public void helloWorld() {
return "Hello World!";
}
Это позволяет нам запускать методы и фрагменты кода каждый раз, когда конечный пользователь попадает в конечную точку с помощью HTTP-запроса. В данном случае это простое корневое сопоставление, которое возвращает строку «Hello World!». при попадании в корневую конечную точку.
Аннотация @RequestMapping
Сама @RequestMapping
предлагает больше, чем показано в предыдущем
примере. Кратко рассмотрим некоторые из основных вариантов использования
аннотации.
@RequestMapping Scopes
Отображение может быть назначено на уровне класса или на уровне метода:
@RequestMapping("/admin")
public class AdminController() {
@RequestMapping("/adminPanel")
public String adminPanel() {
return "adminPanel.html";
}
@RequestMapping("/statistics")
public String statistics() {
return "statistics.html";
}
}
Здесь /admin
назначается на уровне класса, тогда как /adminPanel
и
/statistics
назначаются методам. Сопоставление уровня класса будет
использоваться в качестве префикса для всех этих сопоставлений уровня
метода: /admin/adminPanel
и /admin/statistics
.
Таким образом, мы можем разделить наше приложение на логические части.
Например, вся логика, связанная с администратором, будет находиться за
/admin
, в которую могут войти только пользователи-администраторы. Все
пользователи без прав администратора будут перенаправлены на клиентскую
часть приложения.
Множественные сопоставления для каждого метода
При необходимости мы можем назначить несколько сопоставлений одному методу, например:
@RequestMapping("/", "/index", "/home")
public void helloWorld() {
return "Hello World!";
}
Попадание в любую из этих конечных точек приведет к тому, что
helloWorld()
обрабатывать наш запрос.
Способы запроса
Наиболее часто используемый атрибут - это method
который позволяет нам
указать и сузить метод запроса, который обрабатывает наш метод ( GET ,
POST , DELETE и т. Д.):
@RequestMapping(value = "/addProduct", method = RequestMethod.POST)
public String addProductPost(@ModelAttribute("product") Product product) {
// some code
}
Если мы не указываем метод запроса, метод запроса по умолчанию - GET
.
Заголовки запроса
Мы можем дополнительно указать отображение, определив один или несколько
заголовков. В этом случае метод helloWorld()
будет обрабатывать
запрос, если его content-type
- text/plain
или text/html
:
@RequestMapping(value = "/header", headers = {"content-type=text/plain", "content-type=text/html"})
String helloWorld() {
return "Hello World!";
}
Переменные пути
Многие веб-сайты полагаются на переменные пути, чтобы продемонстрировать
конечному пользователю конкретный продукт, страницу, профиль и т. Д.,
Например example.com/viewProduct/324
, где 324
- это идентификатор
продукта:
@RequestMapping("/viewProduct/{productId}")
public String viewProduct(@PathVariable int productId, Model model) {
Product product = productService.getProductById(productId);
model.addAttribute("product", product);
return "viewProduct";
}
Здесь, после сопоставления, мы заключаем переменную пути в фигурные
скобки ( {}
) и присваиваем это значение нашему productId
. Об этом
@PathVariable
аннотация @PathVariable. Затем мы можем найти продукт
через нашу ProductService
и показать его конечному пользователю.
Конечно, тот же подход можно использовать и для других переменных, таких как:
@RequestMapping("/users/{username}")
public String viewUser(@PathVariable("username") String username) {
Profile profile = profileService.getProfileByUsername(username);
// rest of the code
}
Параметры запроса
Подобно переменным пути, многие приложения полагаются на параметры
запроса для изменения состояния страницы. Мы можем использовать
@RequestParam
для привязки параметра запроса к переменной:
@RequestMapping("/login")
public String login(@RequestParam(value = "error", required = false) String error, @RequestParam(value = "logout", required = false) String logout, Model model) {
if (error != null) {
model.addAttribute("error", "Wrong username or password!");
}
if (logout != null) {
model.addAttribute("msg", "You have successfully logged out!");
}
return "login";
}
Производимые и расходные материалы
Используя @RequestMapping
, мы также можем создавать или потреблять
типы мультимедиа. Для получения медиа - типа , такая как «JSON», вы
можете использовать produces
атрибут наряду с @ResponseBody
аннотации, а потреблять СМИ типа вы можете использовать consumes
атрибут:
@RequestMapping("/annotations")
public class SomeController {
@RequestMapping(value = "/produce", produces = {"application/json"})
@ResponseBody
String produces() {
return "Here's how you use the 'produces' attribute";
}
@RequestMapping(value = "/consume", consumes = {"application/JSON", "application/XML"})
String consume() {
return "Here's how you use a 'consume' attribute";
}
}
Составлены варианты @RequestMapping
Одно отображение может соответствовать разным методам, если мы гарантируем отсутствие двусмысленности в том, какой метод должен обрабатывать какую версию отображения.
У нас может быть несколько методов с одинаковым отображением, если их метод запроса отличается:
@RequestMapping("/hello")
public String hello() {
return "hello";
}
@RequestMapping(value = "/hello", method = RequestMethod.POST)
public String helloPost() {
return "hello post";
}
@RequestMapping(value = "/hello", method = RequestMethod.PUT)
public String helloGet() {
return "hello put";
}
@RequestMapping(value = "/hello", method = RequestMethod.DELETE)
public String helloDelete() {
return "hello delete";
}
У этого же метода есть 4 различных варианта:
- По умолчанию (GET)
- ПОЧТА
- СТАВИТЬ
- УДАЛИТЬ
Чем больше вариаций, тем меньше читаемость кода, и, честно говоря, это уже многословно для простого отображения. Сопоставления запросов в более крупных приложениях могут быть очень сложными и запутанными, и мы хотели бы сделать их более простыми и удобочитаемыми.
Для этого мы познакомились с несколькими новыми аннотациями, вариантами
@RequestMapping
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
@PatchMapping
Существуют буквально только сокращенные версии для отображений выше, где
@PostMapping("/hello")
равно
@RequestMapping(value="/hello", RequestMethod.POST)
.
Присмотревшись к определению этих аннотаций, мы сможем получить четкое представление о том, что они делают:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
@AliasFor(annotation = RequestMapping.class)
String name() default "";
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
}
При этом мы можем переписать приведенные выше примеры:
@GetMapping
public String hello() {
return "hello";
}
@PostMapping
public String helloPost() {
return "hello post";
}
@PutMapping
public String helloGet() {
return "hello put";
}
@DeleteMapping
public String helloDelete() {
return "hello delete";
}
Поскольку это и более простой, более читаемый и новый способ написания
аннотаций, обычно предпочтительнее писать их вот так. При необходимости
вы все равно можете определить любые другие атрибуты, такие как value
, params
, path
и т. Д.
Заключение
@RequestMapping
- это типичная аннотация в среде Spring, которая
позволяет нам сопоставлять HTTP-запросы с методами, которые мы хотели бы
запустить.
Начиная с Spring 4.3, рекомендуется и рекомендуется использовать ярлыки, сделанные для этой аннотации, для более удобочитаемой и менее подробной кодовой базы.