web-dev-qa-db-ja.com

Spring Bootのホワイトラベルの削除エラーページ

ホワイトラベルのエラーページを削除しようとしているので、 "/ 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

私が何か悪いことをしているのかどうかわからない。アドバイスを下さい。

編集:

Application.propertiesファイルにerror.whitelabel.enabled=falseが既に追加されていますが、それでも同じエラーが発生します

136

コードを次のように変更する必要があります。

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

BasicErrorControllerの実装を指定していない場合、Spring Bootは自動的にErrorControllerをSpring Beanとして登録するため、コードは機能しませんでした。

その事実を見るには、ここでErrorMvcAutoConfiguration.basicErrorControllerにナビゲートしてください

219
geoand

もっと「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);
  }
}
41
acohen

Spring bootのドキュメント は間違っていました(それ以来修正されています):

無効にするには、error.whitelabel.enabled= falseを設定します。

あるべき

無効にするには、server.error.whitelabel.enabled= falseと設定します。

33
willome

次のように指定すると完全に削除できます。

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

ただし、そうするとサーブレットコンテナのホワイトラベルページが代わりに表示されることがあります。


編集:これを行う別の方法はapplication.yamlを介してです。値を入れるだけです:

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

ドキュメント

Spring Boot <2.0の場合、クラスはパッケージorg.springframework.boot.autoconfigure.webにあります。

30
hoodieman

Manual here は標準エラーページを無効にするためにserver.error.whitelabel.enabledfalseに設定する必要があることを示しています。たぶんそれはあなたが望むものですか?

ところで、エラーマッピングを追加した後も同じエラーが発生します。

15
Innot Kauker

Spring Boot> 1.4.xでは、これを実行できます。

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

ただし、例外が発生した場合、サーブレットコンテナは独自のエラーページを表示します。

11
db80

これはあなたの春のブートバージョンによって異なります。

SpringBootVersion <= 1.2の場合はerror.whitelabel.enabled = falseを使用

SpringBootVersion > = 1.3の場合はserver.error.whitelabel.enabled = falseを使用

6
sendon1982

Moustacheテンプレートを使用するSpring Boot 1.4.1では、templatesフォルダの下に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のインターセプターを作成することで追加の変数を渡すことができます

5
Ecmel Ercan

これは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にすることもできます。

2
rustyx

server.error.whitelabel.enabled = false

上記の行をResourcesフォルダーのapplication.propertiesに含めます。

その他のエラー問題の解決参照してください http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page

1

私はSpring Bootバージョン2.1.2を使用していますが、errorAttributes.getErrorAttributes()シグネチャは私のために機能しませんでした(そのため)。私はJSONタイプのレスポンスが欲しいので少し掘り下げてみて、このメソッドがまさに私が必要としていることを実行していることがわかりました。

私は、この ブログ記事 と同様に、このスレッドから私の情報の大部分を得ました。

最初に、Springがエラーをマッピングするために探すCustomErrorControllerを作成しました。

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

次に、エラーをJSONとして返すためのCustomHttpErrorResponseクラスを作成しました。

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
}

最後に、私はapplication.propertiesファイルでWhitelabelを消さなければなりませんでした。

server.error.whitelabel.enabled=false

これはxmlリクエスト/レスポンスにさえ働くべきです。しかし、私はそれをテストしていません。 RESTful APIを作成していて、JSONのみを返したかったので、私が探していたこととまったく同じでした。

0
David House

マイクロサービスからRESTエンドポイントを呼び出そうとしていましたが、resttemplateのputメソッドを使用していました。

私の設計では、エラーがRESTエンドポイント内で発生した場合、JSONエラー応答を返すはずです。これは一部の呼び出しでは機能していましたが、このputエラーではなく、ホワイトラベルエラーが返されました。代わりにpage.

それで私はいくつかの調査をしました、そして、私はそれを見つけました。

Springは呼び出し元がマシンであるかどうかを理解しようとするとJSON応答を返すか、またはブラウザである場合はホワイトラベルエラーページ HTMLを返します。

結果として、私のクライアントアプリはRESTエンドポイントに対して、呼び出し元はブラウザではなくマシンであると言う必要がありました。そのため、クライアントアプリは 'application/json'をACCEPTに追加する必要がありました。 resttemplateの 'put'メソッドのための明示的なヘッダ。これをヘッダーに追加して問題を解決しました。

エンドポイントへの私の電話:

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

上記の呼び出しのために、私は以下のヘッダパラメータを追加しなければなりませんでした。

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

または、私は交換にputを変更しようとしました、この場合、交換呼び出しは私のために同じヘッダーを追加して、あまりにも問題を解決しました、しかし、私はなぜかわかりません:)

restTemplate.exchange(....)
0
cazador