ホワイトラベルのエラーページを削除しようとしているので、 "/ 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
が既に追加されていますが、それでも同じエラーが発生します
コードを次のように変更する必要があります。
@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
にナビゲートしてください 。
もっと「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);
}
}
Spring bootのドキュメント は間違っていました(それ以来修正されています):
無効にするには、error.whitelabel.enabled= falseを設定します。
あるべき
無効にするには、server.error.whitelabel.enabled= falseと設定します。
次のように指定すると完全に削除できます。
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
にあります。
Manual here は標準エラーページを無効にするためにserver.error.whitelabel.enabled
をfalse
に設定する必要があることを示しています。たぶんそれはあなたが望むものですか?
ところで、エラーマッピングを追加した後も同じエラーが発生します。
Spring Boot> 1.4.xでは、これを実行できます。
@SpringBootApplication(exclude = {ErrorMvcAutoConfiguration.class})
public class MyApi {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
ただし、例外が発生した場合、サーブレットコンテナは独自のエラーページを表示します。
これはあなたの春のブートバージョンによって異なります。
SpringBootVersion <= 1.2
の場合はerror.whitelabel.enabled = false
を使用
SpringBootVersion > = 1.3
の場合はserver.error.whitelabel.enabled = false
を使用
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
のインターセプターを作成することで追加の変数を渡すことができます
これは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
にすることもできます。
上記の行をResourcesフォルダーのapplication.propertiesに含めます。
その他のエラー問題の解決参照してください http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-customize-the-whitelabel-error-page
私は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のみを返したかったので、私が探していたこととまったく同じでした。
マイクロサービスから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(....)