spring mvc Página de erro do arranque de mola Remover Whitelabel




spring boot index html (10)

Estou tentando remover a página de erro de etiqueta branca, então o que eu fiz foi criar um mapeamento de controlador para "/ error",

@RestController
public class IndexController {

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

}

Mas agora eu estou recebendo esse erro.

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

Não sei se estou fazendo algo errado. Conselho por favor.

EDITAR:

Já adicionei error.whitelabel.enabled=false ao arquivo application.properties, ainda recebendo o mesmo erro


Answer #1

Eu estava tentando chamar um endpoint REST de um microservice e estava usando o método put do resttemplate.

Em meu design, se algum erro ocorresse dentro do endpoint REST, ele deveria retornar uma resposta de erro JSON, ele estava funcionando para algumas chamadas, mas não para essa put , retornou a página de erro de etiqueta branca .

Então eu fiz algumas investigações e descobri isso;

Primavera tentar entender o chamador se é uma máquina, em seguida, ele retorna a resposta JSON ou se é um navegador que retorna a página HTML de erro de etiqueta branca .

Como resultado: meu aplicativo cliente precisava dizer ao terminal REST que o chamador é uma máquina, não um navegador, portanto, para isso, o aplicativo cliente precisava incluir ' application / json ' no cabeçalho ACCEPT explicitamente para o método 'put' do modem de repouso. Eu adicionei isso ao cabeçalho e resolvi o problema.

minha chamada para o endpoint:

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

para a chamada acima eu tive que adicionar abaixo do parâmetro de cabeçalho.

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

ou eu tentei mudar de posto para trocar também, nesse caso, troca de chamadas adicionei o mesmo cabeçalho pra mim e resolvi o problema também mas não sei por que :)

restTemplate.exchange(....)

Answer #2

Manual here diz que você tem que definir server.error.whitelabel.enabled para false para desativar a página de erro padrão. Talvez seja o que você quer?

Estou passando pelo mesmo erro após adicionar / mapeamento de erro, a propósito.


Answer #3

Com o Spring Boot> 1.4.x você pode fazer isso:

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

mas, em caso de exceção, o contêiner do servlet exibirá sua própria página de erro.


Answer #4

Estou usando o Spring Boot versão 2.1.2 e a assinatura errorAttributes.getErrorAttributes() não funcionou para mim (na resposta do acohen). Eu queria uma resposta do tipo JSON, então fiz uma pequena pesquisa e descobri que esse método fazia exatamente o que eu precisava.

Eu obtive a maioria das minhas informações deste tópico, bem como desta postagem do blog .

Primeiro, eu criei um CustomErrorController que o Spring irá procurar para mapear quaisquer erros.

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;
    }
}

Em segundo lugar, criei uma classe CustomHttpErrorResponse para retornar o erro como 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
}

Finalmente, tive que desativar o Whitelabel no arquivo application.properties .

server.error.whitelabel.enabled=false

Isso deve funcionar para solicitações / respostas xml . Mas eu não testei isso. Ele fez exatamente o que eu estava procurando desde que eu estava criando uma API RESTful e só queria retornar JSON.


Answer #5

Isso depende da sua versão de inicialização por mola:

Quando SpringBootVersion <= 1.2 , use error.whitelabel.enabled = false

Quando SpringBootVersion > = 1.3 , use server.error.whitelabel.enabled = false


Answer #6

Aqui está um método alternativo que é muito semelhante ao "modo antigo" de especificar mapeamentos de erros em web.xml .

Basta adicionar isso à sua configuração do 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"));
    }

}

Então você pode definir as páginas de erro no conteúdo estático normalmente.

O personalizador também pode ser um @Component separado, se desejado.


Answer #7

No Spring Boot 1.4.1 usando modelos Mustache, colocar error.html na pasta templates será suficiente:

<!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>

Variáveis ​​adicionais podem ser passadas criando um interceptor para /error


Answer #8

Se você quiser uma página de resposta mais "JSONish", você pode tentar algo assim:

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);
  }
}

Answer #9

Você precisa alterar seu código para o seguinte:

@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;
    }
}

Seu código não funcionou, porque o Spring Boot registra automaticamente o BasicErrorController como um Spring Bean quando você não especificou uma implementação do ErrorController .

Para ver esse fato, navegue até ErrorMvcAutoConfiguration.basicErrorController here .


Answer #10

Você pode removê-lo completamente, especificando:

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

No entanto, observe que isso provavelmente fará com que as páginas de whitelabel do contêiner do servlet sejam exibidas :)

EDIT: Outra maneira de fazer isso é via application.yaml. Basta colocar o valor:

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

Documentation

Para Spring Boot <2.0, a classe está localizada em package org.springframework.boot.autoconfigure.web .





spring-boot