Spring Boot — пример класса обслуживания для отображения кодов ответов и пользовательских кодов ошибок

Опубликовано: 10 Января, 2023

Иногда сообщения об ошибках или статусе на веб-страницах будут отличаться от сообщений об ошибках по умолчанию, выдаваемых Tomcat (или любым другим сервером). Важной причиной этого является то, что веб-сайты хотят выглядеть уникальными в своем подходе к своим пользователям. Таким образом, настроенная страница для отображения кодов состояния всегда лучше, чем стандартный шаблон. В этом случае Spring Boot упрощает обработку нескольких возможностей неправильных URL-адресов, введенных пользователем. Начнем с того, что Spring Boot достаточно прост для базовых конфигураций с помощью Spring Initializr (https://start.spring.io/). После перехода на стартовый сайт необходимо выполнить следующие шаги:

  1. На сайте уже будут значения по умолчанию для группы, артефакта, имени пакета и т. д., которые можно изменить в соответствии с требованиями.
  2. Последняя стабильная версия Spring была бы выбрана в стартере по умолчанию, но вы можете попробовать нестабильные версии SNAPSHOT и M3, если хотите.
  3. Также есть возможность добавить зависимости. Для нашего руководства мы будем кодировать только веб-сервисы RESTful, будет достаточно добавить зависимость Spring Web и Spring Boot DevTools. Spring Boot DevTools обеспечивает более быстрый перезапуск приложения, LiveReload и другие конфигурации, которые гарантируют, что разработчику не нужно перезапускать приложение каждый раз при изменении кода.

После всех шагов проект можно скачать в виде zip-файла. После извлечения содержимого из zip-файлов его можно импортировать в среду IDE, щелкнув:

  1. Импорт -> Maven -> Существующие проекты Maven -> Далее
  2. Нажмите «Обзор», перейдите в папку, в которую загружен проект, выберите папку проекта и нажмите «Выбрать папку».

Теперь пришло время упомянуть ожидаемые результаты этого урока. Ожидаемый результат демонстрируется скриншотами. Ожидается, что класс службы будет отображать выходные данные только для запросов GET, другие методы должны отображать код ошибки 405.

Если значения параметров не соответствуют указанным возможным значениям или параметр отсутствует, должна отображаться страница ошибки «Страница не найдена».

Запрос GET /format=text должен возвращать простое ответное сообщение, отображающее текущее время и код состояния как OK, с использованием HashMap в качестве формата данных ответа.

Запрос GET /format=page должен отображать веб-страницу. Это субъективно в каждом случае, и в этом случае мы будем отображать только образец веб-страницы, доступной в открытом доступе.

Вышеуказанные требования могут быть закодированы в классах контроллеров, аннотированных аннотацией @RestController, как показано в примере, приведенном ниже.

Файл Controller.java

Java




package com.springboot.springbootdemo;
  
import java.lang.annotation.Repeatable;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.MethodNotAllowedException;
  
@RestController
public class Controller implements ErrorController {
  
    @GetMapping("/format=page")
    public ResponseEntity<Object> page()
    {
        return ResponseEntity.status(HttpStatus.FOUND)
            .location(URI.create(
            .build();
    }
  
    @GetMapping("/format=text")
    public HashMap<String, String> text()
    {
        HashMap<String, String> map
            = new HashMap<String, String>();
        SimpleDateFormat formatter = new SimpleDateFormat(
            "yyyy-MM-dd"T"HH:mm:ssZ");
        Date date = new Date(System.currentTimeMillis());
        String formattedString = formatter.format(date);
        map.put("currentTime", formattedString);
        map.put("status", "OK");
        return map;
    }
  
    @PostMapping("/**")
    public HashMap<String, String> all_except_get()
    {
        HashMap<String, String> map
            = new HashMap<String, String>();
        map.put("status", "401");
        return map;
    }
  
    @DeleteMapping("/**")
    public HashMap<String, String> all_delete()
    {
        HashMap<String, String> map = all_except_get();
        return map;
    }
  
    @PutMapping("/**")
    public HashMap<String, String> all_put()
    {
        HashMap<String, String> map = all_except_get();
        return map;
    }
  
    @PatchMapping("/**")
    public HashMap<String, String> all_patch()
    {
        HashMap<String, String> map = all_except_get();
        return map;
    }
  
    @RequestMapping("/error")
    public ResponseEntity<Object> handleError()
    {
        return ResponseEntity.status(HttpStatus.FOUND)
            .location(URI.create(
                "http://localhost:8002/LoginRegistration/404error.html"))
            .build();
    }
  
    public String getErrorPath() { return "/error"; }
}

Объяснение приведенного выше кода:

  • Функция ResponseEntity<Object> page() с аннотацией @GetMapping("/format=page") обрабатывает запросы к GET /format=page, перенаправляя элемент управления на веб-страницу "https://www.geeksforgeeks.org/resource-injection". -in-java-ee/» с помощью команды «return ResponseEntity.status(HttpStatus.FOUND).location(URI.create(“https://www.geeksforgeeks.org/resource-injection-in-java-ee/” )).строить();'
  • URI.create() создает новый объект URI, который анализирует ссылку веб-страницы как URI.
  • Метод location() ищет расположение URI, на который должен быть перенаправлен элемент управления. HttpStatus.FOUND возвращает код ответа, который указывает, доступен ли URL-адрес или нет.
  • Метод build() строит весь этот поток команд, который затем обрабатывается ResponseEntity.status. Затем весь этот ответ возвращается функцией Java, после чего элемент управления перенаправляется на заданный URL-адрес в зависимости от кода состояния для запроса.
  • Функция ResponseEntity<Object> text с аннотацией @GetMapping(“/format=text”) обрабатывает запросы GET /format=text, объявляя и возвращая объект типа HashMap<String, String>.
  • Объект возвращает HashMap с двумя парами ключ-значение. Одна пара ключ-значение — это код состояния с сообщением «ОК», а другая пара ключ-значение — текущая дата и время в формате строки ISO 8601, т. е. в формате «гггг-ММ-дд'Т'ЧЧ:мм». Формат «Z».
  • Вышеупомянутый формат может быть получен с помощью команды форматирования «SimpleDateFormat formatter = new SimpleDateFormat («гггг-ММ-дд'Т'ЧЧ: мм: ссZ»);». Текущие дата и время сохраняются в переменной с помощью команды «Date date = new Date(System.currentTimeMillis());» который затем форматируется в строку с помощью средства форматирования «String formattedString=formatter.format(date);» которую мы только что объявили.
  • Отформатированная строка затем добавляется на карту вместе с сообщением о состоянии. Теперь сообщение, которое будет отображаться для соответствующего URL-адреса, возвращается в виде карты.
  • Поскольку служба должна обрабатывать только запросы GET, а для других запросов должна отображаться ошибка 405, («/**») используется после каждого сопоставления аннотаций для получения всех запросов для данного типа (POST, PUT, DELETE и PATCH) и выдает сообщение об ошибке 405.

Например,

Java




@PostMapping("/**")
public HashMap<String, String> all_except_get()
{
    HashMap<String, String> map
        = new HashMap<String, String>();
    map.put("status", "405");
    return map;
}

это функция для обработки всех запросов POST. Точно так же приведенная ниже функция обрабатывает все запросы DELETE:

Java




@PutMapping("/**")
public HashMap<String, String> all_put() {
HashMap<String, String> map = all_except_get();
     return map;
}

Как видно из приведенного выше кода, карту с кодом состояния не нужно каждый раз объявлять и возвращать. Поскольку она уже была определена один раз, функция вызывается для получения значения карты в переменной, которая затем возвращается. Та же процедура применяется для @DeleteMapping(“/**”) и @PatchMapping(“/**”).

Файл application.properties

server.port=8075
server.error.whitelabel.enabled=false

Перед кодированием пользовательских методов обработчика ошибок необходимо добавить строки «server.error.whitelabel.enabled=false» в файл application.properties , чтобы можно было переопределить страницу ошибок whitelabel по умолчанию.

Note: Spring Boot uses port 8080 by default to start Tomcat. If it is required to use a different port, the port number has to be mentioned in the application.properties file with the server.port=8075.

Теперь вернемся к кодированию методов обработчика ошибок в сервисном классе. Метод getErrorPath() возвращает путь к странице с ошибкой, которая в данном случае возвращает «/error», добавленную к URL-адресу. Впоследствии должна быть функция для обработки URL-адреса ошибки, который приведен ниже:

Java




@RequestMapping("/error")
public ResponseEntity<Object> handleError()
{
    return ResponseEntity.status(HttpStatus.FOUND)
        .location(URI.create(
        .build();
}

Подобно тому, как это было продемонстрировано для @GetMapping("/format=page"), оператор return передает управление странице с ошибкой. Некоторые функции, которые можно закодировать с помощью класса службы, включая пользовательскую функцию ошибок, демонстрируются и поясняются в примерах, приведенных выше.