Spring Boot Удалить страницу ошибки Whitelabel

156

Я пытаюсь удалить страницу с ошибкой белой метки, поэтому я создал отображение контроллера для "/ error",

@RestController
public class IndexController {

    @RequestMapping(value = "/error")
    public String error() {
        return "Error handling";
    }

}

Но теперь я получаю эту ошибку.

Exception in thread "AWT-EventQueue-0" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource   [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Invocation  of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'basicErrorController' bean method 
public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>>  org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletR equest)
to {[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'indexController' bean method

Не знаю, делаю ли я что-то не так. Пожалуйста посоветуй.

РЕДАКТИРОВАТЬ:

Уже добавлено error.whitelabel.enabled=false в файл application.properties, но ошибка та же

Ясита Вадуге
источник
1
Посмотрите на этот проект github.com/paulc4/mvc-exceptions/blob/master/src/main/java/… , кажется, в нем есть переотображение страницы с ошибкой.
Иннот Каукер
Вы пробовали установку spring.resources.add-mappings=false?
гео и
Спасибо за предложение, Да все еще получил ту же ошибку
Yasitha Waduge
Вы просто пытаетесь вернуть пользовательский контент при /errorвызове пути?
гео и

Ответы:

240

Вам нужно изменить свой код на следующее:

@RestController
public class IndexController implements ErrorController{

    private static final String PATH = "/error";

    @RequestMapping(value = PATH)
    public String error() {
        return "Error handling";
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}

Ваш код не работал, потому что Spring Boot автоматически регистрирует BasicErrorControllerкак Spring Bean, когда вы не указали реализацию ErrorController.

Чтобы увидеть этот факт просто перейдите ErrorMvcAutoConfiguration.basicErrorController сюда .

geoand
источник
1
Я столкнулся с той же самой проблемой, я искал документы Spring, но там не упоминалось BasicErrorController. Это работает :)
Mike R
4
Я должен был пройти через источник, чтобы найти этот :-)
geoand
1
Спасибо, отлично сработало! Небольшое продолжение, если вы можете дать какие-либо указатели: скажем, мы попали в этот обработчик ошибок, потому что в нашем приложении возникло исключение (и Spring неявно устанавливает код ответа 500, что является правильным); Есть ли простой способ получить это исключение здесь (чтобы включить некоторые детали в возвращаемое сообщение об ошибке)?
Джоник
1
Рад, что вы нашли это полезным! Хотя я этого не пробовал, я почти уверен, что вы можете использовать принципы, изложенные в Spring Boot BasicErrorController(см. Github.com/spring-projects/spring-boot/blob/… ), чтобы достичь желаемого
гео и
3
Хм, да, еще раз спасибо! Сначала я не был уверен, как получить этот ErrorAttributesобъект (содержащий подробности ошибки), но затем я попытался просто @Autowiring его, и он работает. То, чем я занимался сейчас: gist.github.com/jonikarppinen/662c38fb57a23de61c8b
Jonik,
44

Если вам нужна более «JSONish» страница ответа, вы можете попробовать что-то вроде этого:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/error")
public class SimpleErrorController implements ErrorController {

  private final ErrorAttributes errorAttributes;

  @Autowired
  public SimpleErrorController(ErrorAttributes errorAttributes) {
    Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
    this.errorAttributes = errorAttributes;
  }

  @Override
  public String getErrorPath() {
    return "/error";
  }

  @RequestMapping
  public Map<String, Object> error(HttpServletRequest aRequest){
     Map<String, Object> body = getErrorAttributes(aRequest,getTraceParameter(aRequest));
     String trace = (String) body.get("trace");
     if(trace != null){
       String[] lines = trace.split("\n\t");
       body.put("trace", lines);
     }
     return body;
  }

  private boolean getTraceParameter(HttpServletRequest request) {
    String parameter = request.getParameter("trace");
    if (parameter == null) {
        return false;
    }
    return !"false".equals(parameter.toLowerCase());
  }

  private Map<String, Object> getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest);
    return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
  }
}
acohen
источник
7
В Spring-Boot v2 классы ErrorController и ErrorAttributes находятся в пакете org.springframework.boot.web.servlet.error и, кроме того, изменилась сигнатура метода ErrorAttributes # getErrorAttributes, обратите внимание на зависимость от Spring-Boot v1 и, возможно, дайте подсказки для v2, Спасибо.
chrisinmtown
1
Изменение: private Map <String, Object> getErrorAttributes (HttpServletRequest aRequest, логическое значение includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes (aRequest); return errorAttributes.getErrorAttributes (requestAttributes, includeStackTrace); } By: private Map <String, Object> getErrorAttributes (запрос HttpServletRequest, логическое значение includeStackTrace) {WebRequest webRequest = new ServletWebRequest (запрос); вернуть this.errorAttributes.getErrorAttributes (webRequest, includeStackTrace); }
Rija Ramampiandra
2
Обновленная версия SimpleErrorController.java с учетом комментариев, приведенных выше, может быть найдена здесь> gist.github.com/oscarnevarezleal/…
Оскар Неварез,
38

Spring boot doc «был» не прав (с тех пор они это исправили):

Чтобы отключить его, вы можете установить error.whitelabel.enabled = false

должно быть

Чтобы отключить его, вы можете установить server.error.whitelabel.enabled = false

willome
источник
Это отключит страницу ошибки White Label, но весенняя загрузка все /errorравно отобразит конечную точку . Чтобы освободить /errorнабор конечных точек server.error.path=/error-springили какой-либо альтернативный путь.
заметки-
32

Вы можете полностью удалить его, указав:

import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
...
@Configuration
@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
public static MainApp { ... }

Тем не менее, обратите внимание, что это, вероятно, приведет к тому, что вместо этого появятся страницы whitelabel контейнера сервлета :)


РЕДАКТИРОВАТЬ: Другой способ сделать это через application.yaml. Просто введите значение:

spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

Документация

Для Spring Boot <2.0 класс находится в пакете org.springframework.boot.autoconfigure.web.

hoodieman
источник
15

Руководство здесь говорит , что вы должны установить server.error.whitelabel.enabledдля falseотключить стандартную страницу ошибки. Может быть, это то, что вы хотите?

Я испытываю ту же ошибку после добавления / отображения ошибок, кстати.

Иннот Каукер
источник
Да, я уже установил error.whitelabel.enabled = false, но все еще получаю ту же ошибку после добавления / отображения ошибок
Yasitha Waduge
Это отключит страницу ошибки White Label, но весенняя загрузка все /errorравно отобразит конечную точку . Чтобы освободить /errorнабор конечных точек server.error.path=/error-springили какой-либо альтернативный путь.
заметки-
11

С Spring Boot> 1.4.x вы можете сделать это:

@SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class})
public class MyApi {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

но тогда в случае исключения контейнер сервлета отобразит свою собственную страницу ошибки.

db80
источник
8

Это зависит от вашей весенней загрузки:

Когда SpringBootVersion <=, 1.2тогда используйтеerror.whitelabel.enabled = false

Когда SpringBootVersion > =, 1.3тогда используйтеserver.error.whitelabel.enabled = false

sendon1982
источник
6

В Spring Boot 1.4.1 с использованием шаблонов Mustache достаточно поместить error.html в папку шаблонов:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Error</title>
</head>

<body>
  <h1>Error {{ status }}</h1>
  <p>{{ error }}</p>
  <p>{{ message }}</p>
  <p>{{ path }}</p>
</body>

</html>

Дополнительные переменные могут быть переданы путем создания перехватчика для /error

Экмель Эркан
источник
Используя этот пример: github.com/paulc4/mvc-exceptions/blob/master/src/main/resources/…
e-info128
3

Вот альтернативный метод, который очень похож на «старый способ» определения отображений ошибок в web.xml .

Просто добавьте это в конфигурацию Spring Boot:

@SpringBootApplication
public class Application implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        factory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/errors/403.html"));
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/404.html"));
        factory.addErrorPages(new ErrorPage("/errors/500.html"));
    }

}

Затем вы можете определить страницы ошибок в статическом контенте как обычно.

Настройщик также может быть отдельным @Component, при желании.

rustyx
источник
3

Я использую Spring Boot версии 2.1.2, и errorAttributes.getErrorAttributes()подпись не работает для меня (в ответ acohen). Я хотел получить ответ типа JSON, поэтому немного покопался и обнаружил, что этот метод сделал именно то, что мне нужно.

Я получил большую часть своей информации из этой темы, а также из этого блога .

Во-первых, я создал, CustomErrorControllerчто Spring будет искать для сопоставления любых ошибок.

package com.example.error;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
public class CustomErrorController implements ErrorController {

    private static final String PATH = "error";

    @Value("${debug}")
    private boolean debug;

    @Autowired
    private ErrorAttributes errorAttributes;

    @RequestMapping(PATH)
    @ResponseBody
    public CustomHttpErrorResponse error(WebRequest request, HttpServletResponse response) {
        return new CustomHttpErrorResponse(response.getStatus(), getErrorAttributes(request));
    }

    public void setErrorAttributes(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }

    private Map<String, Object> getErrorAttributes(WebRequest request) {
        Map<String, Object> map = new HashMap<>();
        map.putAll(this.errorAttributes.getErrorAttributes(request, this.debug));
        return map;
    }
}

Во-вторых, я создал CustomHttpErrorResponseкласс, который возвращает ошибку как JSON.

package com.example.error;

import java.util.Map;

public class CustomHttpErrorResponse {

    private Integer status;
    private String path;
    private String errorMessage;
    private String timeStamp;
    private String trace;

    public CustomHttpErrorResponse(int status, Map<String, Object> errorAttributes) {
        this.setStatus(status);
        this.setPath((String) errorAttributes.get("path"));
        this.setErrorMessage((String) errorAttributes.get("message"));
        this.setTimeStamp(errorAttributes.get("timestamp").toString());
        this.setTrace((String) errorAttributes.get("trace"));
    }

    // getters and setters
}

Наконец, мне пришлось отключить Whitelabel в application.propertiesфайле.

server.error.whitelabel.enabled=false

Это должно даже работать для xmlзапросов / ответов. Но я не проверял это. Он сделал именно то, что я искал, так как я создавал RESTful API и хотел только вернуть JSON.

DJ House
источник
2

server.error.whitelabel.enabled = ложь

Включите указанную выше строку в папку «Ресурсы» application.properties

Подробнее об устранении проблем можно найти по адресу http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

Суганья Сударсан
источник
Я попробовал application.properties в моей папке установки, которая ничего не сделала. Папка application.properties в / src / main / resources - это то, что suganya sudarsan пытался передать. Похоже, что это «горячее чтение» в Eclipse.
Ричард Брэдли Смит
1

Я пытался вызвать REST конечной точки из microservice , и я использовал resttemplate в пут метод.

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

Итак, я провел некоторое расследование и выяснил это;

Spring попытается понять вызывающую программу, если это машина, то она возвращает ответ JSON или браузер, а затем возвращает страницу с ошибкой белой метки HTML.

В результате: мое клиентское приложение должно было сказать конечной точке REST, что вызывающая сторона - это машина, а не браузер, поэтому для этого клиентскому приложению необходимо добавить ' application / json явно ' в заголовок ACCEPT для метода put 'resttemplate. Я добавил это в шапку и решил проблему.

мой звонок в конечную точку:

restTemplate.put(url, request, param1, param2);

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

headers.set("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);

или я попытался изменить пут на обмен, в этом случае обмен вызовами добавил тот же заголовок для меня и тоже решил проблему, но я не знаю почему :)

restTemplate.exchange(....)
Cazador
источник
0

Spring Boot по умолчанию имеет « белую метку» ошибки », которую можно увидеть в браузере, если вы столкнулись с ошибкой сервера. Страница ошибок Whitelabel - это общая страница ошибок Spring Boot, которая отображается, когда пользовательская страница ошибок не найдена.

Установите «server.error.whitelabel.enabled = false» для переключения страницы ошибок по умолчанию

shatakshi
источник
0

У меня возникала похожая проблема с сообщением об ошибке WhiteLabel на моем Angular SPA при каждом обновлении.

Исправление состояло в том, чтобы создать контроллер, который реализует ErrorController, но вместо того, чтобы возвращать String, мне пришлось возвращать объект ModelAndView, который перенаправляет в /

@CrossOrigin
@RestController
public class IndexController implements ErrorController {
    
    private static final String PATH = "/error";
    
    @RequestMapping(value = PATH)
    public ModelAndView saveLeadQuery() {           
        return new ModelAndView("forward:/");
    }

    @Override
    public String getErrorPath() {
        return PATH;
    }
}
Шубхашиш Мишра
источник