3

Spring MVC を使用した REST アプリケーションがいくつかあります。展開後に一部のアプリケーションが起動しないことがあります。Javascript クライアントがリソース URL にアクセスしようとすると、404 ステータス コードが返されます。したがって、そのリソースは存在しないと想定されます。私たちにとってより適切なのは、Tomcat 応答で返される http ステータス 500 です。このデフォルトの Tomcat の動作を変更することは可能ですか?

JBoss(組み込みTomcatを使用)で同様の問題を見つけましたが、答えはありません: https://serverfault.com/questions/367986/mod-jk-fails-to-detect-error-state-because-jboss-gives-404 -not-500

4

2 に答える 2

0

はい、多少の変更で可能です。

私達がすること :

  • 次のようなサーブレットを作成します。

    if (req.getContextPath().isEmpty()){
        resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
    } else {
        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
    }
    
  • このクラスを含む jar を tomcat lib に入れます。

  • conf/web.xml を変更してサーブレットを追加し、マップします*.404

  • グローバル エラー404を に設定し/404.404ます。

    <error-page>
        <error-code>404</error-code>
        <location>/404.404</location>
    </error-page>
    

サーブレットは、ルート アプリケーションとデプロイされたすべてのアプリケーションの両方で呼び出されます。

于 2016-04-23T13:25:30.343 に答える
0

HTTP プロキシ

Tomcat サーバーの前にある種のプロキシ ( など) がある場合、404 を別のステータス コードとエラー ページに変換するように構成できると思います。プロキシがない場合、またはソリューションを自己完結型のままにしたい場合:

カスタム Spring ローダーとサーブレット フィルター

ContextLoaderListenerあなたはSpringを使用しているので、 inを使用してブートストラップしていると思いますweb.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

このクラスは Spring のブートストラップを担当し、これはほとんどの場合、アプリケーションの起動が失敗する原因となるステップです。そのクラスを拡張して例外を飲み込むだけで、サーブレット コンテナーに到達しないため、Tomcat はアプリケーションのデプロイが失敗したとは見なしません。

public class FailSafeLoaderListener extends ContextLoaderListener {

    private static final Logger log = LoggerFactory.getLogger(FailSafeLoaderListener.class);

    @Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            super.contextInitialized(event);
        } catch (Exception e) {
            log.error("", e);
            event.getServletContext().setAttribute("deployException", e);
        }
    }
}

コードは非常に単純です。Spring の初期化が失敗した場合、例外をログに記録し、グローバルにServletContext. の古いローダーを新しいローダーに置き換える必要がありweb.xmlます。

<listener>
    <listener-class>com.blogspot.nurkiewicz.download.FailSafeLoaderListener</listener-class>
</listener>

あとは、グローバル フィルターのサーブレット コンテキストからその属性を読み取り、アプリケーションが Spring の起動に失敗した場合はすべてのリクエストを拒否するだけです。

public class FailSafeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Exception deployException = (Exception) request.getServletContext().getAttribute("deployException");
        if (deployException == null) {
            chain.doFilter(request, response);
        } else {
            ((HttpServletResponse) response).sendError(500, deployException.toString());
        }
    }
}

このフィルターをすべてのリクエストにマップします (またはコントローラーのみ?):

<filter-mapping>
    <filter-name>failSafeFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

解決策はあなたが望むものではないかもしれませんが、一般的な実用的な例を示しています。

于 2012-05-14T20:06:24.437 に答える