Dropwizardは何もしないと指定したURLに対応するページがない場合、
Jerseyの404 エラーページがデフォルトのまま出力されます。
このエラーページを変えたかったのですが、Wicketとの組み合わせでの出し方がわからず、
ハマって、2-3日途方に暮れていました..
出力の仕方をメモします。
素のWicketでのエラーページの設定方法
こちらに記載がありますが、
以下の手順を踏むと、404発生時のエラーぺージを設定できます。
1. Web.xmlにerror-page定義を追加する。
2. 404エラー用のPageクラスを作成する。
3. Applicationクラス内で対象ページmountPageする。
Dropwizard起動からのWicketでのエラーページの設定方法
Web.xmlの設定がDropwizardからだとできず(できたとしてもやりたくはない)、
以下のように設定しました。
そもそも、DropwizardからWicketを起動するにはこちらを参照ください。
1. WicketBundle内で、ErrorPageErrorHandlerを設定する。
WicketBundle#(run)メソッド内でcontext.setErrorHandler()を実行する。
@Override
public void run(WicketConfiguration configuration, Environment environment) throws Exception {
MutableServletContextHandler context = environment.getApplicationContext();
context.addEventListener(new GuiceServletConfig());
FilterHolder filterHolder = getFilterHolder(configuration.isDeployment());
context.addFilter(filterHolder, "/*", DISPATCHER_TYPES);
// Comment
context.addServlet(DefaultServlet.class, "/*");
// Set ErrorHandler
ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
errorHandler.addErrorPage(404, "/404");
context.setErrorHandler(errorHandler);
// Set SessionHandler
context.setSessionHandler(new SessionHandler());
environment.jersey().disable();
}
-
org.eclipse.jetty.servlet.ErrorPageErrorHandlerについて
こちらには、以下のようなメソッドが存在します。- void addErrorPage (Class exception, String uri)
- void addErrorPage (int code, String uri)
- void addErrorPage (int from, int to, String uri)
Web.xmlのerror-page記述と同等の設定を行うことができます。
デフォルトは、org.eclipse.jetty.servlet.ErrorHandler が動作しているのかと思いますが、
こちらは、エラー画面用のHTMLがクラス内に書きつけられていて、それが出力されるようです。
2. 404エラー用のPageクラスを作成する。
- エラーPageの抜粋です。
package xyz.monotalk.xxx;
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.protocol.http.servlet.ErrorAttributes;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.apache.wicket.request.http.WebResponse;
import org.apache.wicket.request.mapper.parameter.PageParameters;
/**
* ErrorPage
*
* @author Kem
*/
public class ErrorPage {
private static final long serialVersionUID = -5540046731407875758L;
@Override
protected void initPage(PageParameters parameters) {
// Get ErrorAttributes
ErrorAttributes errorAttributes = getErrorAttributes();
// Add ErrorMessage
add(new Label("errorMessage", errorAttributes.getStatusCode() + " " + errorAttributes.getMessage())
.setRenderBodyOnly(true));
// Add Top page Link
BookmarkablePageLink link = new BookmarkablePageLink<>("topLink", getApplication().getHomePage());
link.add(new Label("topLinkText", "Top Page"));
add(link);
}
// getHttpServletRequest
private ErrorAttributes getErrorAttributes() {
// Get ErrorAttributes
ServletWebRequest servletWebRequest = (ServletWebRequest) getRequest();
HttpServletRequest request = servletWebRequest.getContainerRequest();
return ErrorAttributes.of(request, "/");
}
@Override
protected void configureResponse(WebResponse response) {
super.configureResponse(response);
response.setStatus(getErrorAttributes().getStatusCode());
}
@Override
public boolean isVersioned() {
return false;
}
@Override
public boolean isErrorPage() {
return true;
}
}
指定されたURLがなかった場合も、
Pageクラス内で、AbortWithHttpErrorCodeExceptionで404エラーを送出した場合も、
エラーぺージクラス内では、javax.servlet.error.status_code、javax.servlet.error.message で、
のエラー情報が取得できたので、org.apache.wicket.protocol.http.servlet.ErrorAttributesを使用して、
エラー情報を取得、その情報を画面に出力するようにしました。
ただ、404しか辿り着くことはないので、メッセージが切りわかる機能が追加されたなのですが…
3. Applicationクラス内で対象ページmountPageする。
3. で実施することは同じです。
補足
ソフト404エラーぺージ
Error Pages and Feedback Messages - Apache Wicket - Apache Software FoundationのExampleに記述されている
@Override
protected void configureResponse() {
super.configureResponse();
getWebRequestCycle().getWebResponse().getHttpServletResponse().setStatus(HttpServletResponse.SC_NOT_FOUND);
}
を記載しないと、
Googleウェブマスターツールが「ソフト404」をレポート表示 | 海外SEO情報ブログの
ソフト404エラーページになるので、外部公開するときは明示的に記載が必要になりそうです。
ただ、URLがMountされていない場合の404は、記載がなくても404になるので、その用途のみに使うなら不要です。
Wicket内部でエラー発生時に遷移させる場合は、明示的に記載が必要になります。
以上です。
コメント