スプリングブートホワイトラベルの削除エラーページ


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/…を見て、エラーページの再マッピングがあるようです。
Innot Kauker 2014

設定してみましたspring.resources.add-mappings=falseか?
geoおよび2014

提案をありがとう、はいまだ同じエラーが発生しました
Yasitha Waduge 2014

/errorパスが呼び出されたときに、カスタムコンテンツを返そうとしているだけですか?
ジオおよび2014

回答:


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

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

その事実を確認するには、ErrorMvcAutoConfiguration.basicErrorController ここに移動してください


1
同じ問題を同じ問題に遭遇し、Springドキュメントを検索しましたが、BasicErrorControllerについては言及していませんでした。これは機能します:)
Mike R

4
これを見つけるためにソースを調べなければなりません
でした

1
ありがとう、うまくいきました!ポインタを与えることができる場合の小さなフォローアップ:アプリでいくつかの例外がスローされたためにこのエラーハンドラーに入るとします(そして、Springは応答コードを500に暗黙的に設定します)。ここでその例外を取得する簡単な方法はありますか(返されるエラーメッセージに詳細を含めるため)?
Jonik、2015

1
お役に立てて嬉しいです!まだ試していませんが、Spring Bootの原則BasicErrorControllergithub.com/spring-projects/spring-boot/blob/…を参照)を使用して、目的を達成できると確信しています。
geoおよび

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

7
Spring-Boot v2では、ErrorControllerクラスとErrorAttributesクラスはパッケージorg.springframework.boot.web.servlet.errorにあり、さらにErrorAttributes#getErrorAttributesメソッドシグネチャが変更されています。Spring-Bootv1への依存関係に注意してください。v2のヒントが表示される可能性があります。どうも。
chrisinmtown

1
変更:プライベートMap <String、Object> getErrorAttributes(HttpServletRequest aRequest、boolean includeStackTrace){RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest); errorAttributes.getErrorAttributes(requestAttributes、includeStackTrace);を返します。}作成者:private Map <String、Object> getErrorAttributes(HttpServletRequest request、boolean includeStackTrace){WebRequest webRequest = new ServletWebRequest(request); this.errorAttributes.getErrorAttributes(webRequest、includeStackTrace);を返します。}
Rija Ramampiandra

2
上記からのコメントを考慮しSimpleErrorController.javaの更新バージョンは、ここで見つけることができます> gist.github.com/oscarnevarezleal/...
オスカーNevarez

38

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

これをオフにするには、error.whitelabel.enabled = falseを設定します。

する必要があります

これをオフに切り替えるには、server.error.whitelabel.enabled = falseを設定します。


これにより、ホワイトラベルエラーページが無効になりますが、スプリングブートは/errorとにかくエンドポイントをマップします。エンドポイント/errorセットserver.error.path=/error-springまたはいくつかの代替パスを解放します。
notes-jj

32

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

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の場合、クラスはpackageにありますorg.springframework.boot.autoconfigure.web


15

ここのマニュアルは、標準エラーページを無効にするように設定server.error.whitelabel.enabledする必要があると述べていますfalse。多分それはあなたが欲しいものですか?

ちなみに、/ errorマッピングを追加した後も同じエラーが発生しています。


はい、すでにerror.whitelabel.enabled = falseを設定していますが、/ errorマッピングを追加した後も同じエラーが発生します
Yasitha Waduge 14

これにより、ホワイトラベルエラーページが無効になりますが、スプリングブートは/errorとにかくエンドポイントをマップします。エンドポイント/errorセットserver.error.path=/error-springまたはいくつかの代替パスを解放します。
notes-jj

11

Spring Boot> 1.4.xでこれを行うことができます:

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

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



6

Mustacheテンプレートを使用するSpring Boot 1.4.1では、errors.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



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必要に応じて、カスタマイザを個別にすることもできます。


3

Spring Bootバージョン2.1.2を使用していerrorAttributes.getErrorAttributes()ますが、署名が機能しません(acohenの応答)。JSON型の応答が必要だったので、少し掘り下げてみたところ、このメソッドが必要なものを正確に実行することがわかりました。

私はほとんどの情報をこのスレッドとこのブログ投稿から取得しました。

まず、CustomErrorControllerSpringがエラーをマッピングするために検索するを作成しました。

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
}

最後に、application.propertiesファイルのホワイトラベルをオフにする必要がありました。

server.error.whitelabel.enabled=false

これはxmlリクエスト/レスポンスでも機能するはずです。しかし、私はそれをテストしていません。RESTful APIを作成していて、JSONを返したいだけだったので、それはまさに私が探していたものを実行しました。


2

server.error.whitelabel.enabled = false

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

エラーの問題をさらに解決するには、http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-pageを参照してください。


何もしないインストールフォルダーでapplication.propertiesを試しました。/ src / main / resourcesの下のapplication.propertiesフォルダーは、suganya sudarsanが伝えようとしていたものです。Eclipseでも「ホットリード」のようです。
Richard Bradley Smith

1

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

私の設計では、RESTエンドポイント内でエラーが発生した場合、JSONエラー応答を返す必要があり、一部の呼び出しでは機能しましたが、このputコールでは機能しませんでした。ホワイトラベルエラーページが返されました代わりに。

だから私はいくつかの調査を行い、それを発見しました。

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

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

エンドポイントへの私の呼び出し:

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

上記の呼び出しでは、ヘッダーパラメータの下に追加する必要がありました。

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

または私は交換のためにプットを変更しようとしました、この場合、エクスチェンジ呼び出しは私のために同じヘッダーを追加して問題も解決しましたが、なぜだかわかりません:)

restTemplate.exchange(....)

0

Spring Bootには、デフォルトで「whitelabel」エラーページがあり、サーバーエラーが発生した場合にブラウザーで確認できます。ホワイトラベルエラーページは、カスタムエラーページが見つからない場合に表示される一般的なSpring Bootエラーページです。

「server.error.whitelabel.enabled = false」を設定して、デフォルトのエラーページを切り替えます


0

更新を行うたびに、Angular SPAで同様の問題のWhiteLabelエラーメッセージが表示されました。

修正は、ErrorControllerを実装するコントローラーを作成することでしたが、文字列を返す代わりに、/に転送する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;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.