【问题标题】:Configured 404 error page not shown in JAX-RS ApplicationJAX-RS 应用程序中未显示配置的 404 错误页面
【发布时间】:2017-06-13 16:07:09
【问题描述】:

我有以下问题:我创建了一个 Java Web 应用程序。此外,我制作了一些 REST 端点。在 web.xml 中,我使用标签定义了 404 错误的重定向。它适用于除不存在的 REST 端点之外的所有地址。我实现了 RestApplication 类:

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest")
public class RestApplication extends Application {
}

还有一个端点,myView:

@Path("/myView")
public class MyView {

    @GET
    @Path("/")
    public Response myViewPage() {
        //some code goes here...
    }
}

现在,当我尝试输入不存在的端点时,假设“aaa”,即我输入地址:http://localhost:8080/mysite/rest/aaa,我收到 404 错误,但重定向不起作用。对于非 REST 地址,例如:http://localhost:8080/mysite/somesitethatdoesnotexist,重定向可以正常工作。我的 web.xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
                            version="3.1">
                            
    <context-param>
       <param-name>resteasy.document.expand.entity.references</param-name>
       <param-value>false</param-value>
    </context-param>

    <servlet>
        <servlet-name>faces</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>faces</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>faces</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>welcome.xhtml</welcome-file>
    </welcome-file-list>
    
    <error-page>
        <error-code>404</error-code>
        <location>/WEB-INF/errorpages/404.xhtml</location>
    </error-page>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>restricted methods</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>PUT</http-method>
            <http-method>DELETE</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>HEAD</http-method>
        </web-resource-collection>
        <auth-constraint />
    </security-constraint>

</web-app>

我也尝试使用 ExceptionMapper,即我实现了 EntityNotFoundExceptionMapper 类:

@Provider
public class EntityNotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {

    @Override
    public Response toResponse(NotFoundException ex) {
      // some code for redirect
    }
}

并将其添加到 RestApplication 类中:

@ApplicationPath("rest")
public class RestApplication extends Application {
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(EntityNotFoundExceptionMapper.class);
        return s;
    }
}

但它没有用。但是,当我删除以下内容时它起作用了:

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/errorpages/404.xhtml</location>
</error-page>

来自 web.xml。但是,不幸的是,重定向当然不适用于非 REST 地址。

谁能帮我解决这个问题并提出解决方案,让我在 REST 和非 REST 地址出现 404 错误时提供重定向?提前谢谢!

编辑:

按照@andih的说法,对于REST服务,我想在资源不可用的情况下返回一个配置的404错误页面。

【问题讨论】:

  • 您能否更详细地解释您的期望。 Http 状态码 404 表示“未找到”。没有重定向。你想重定向谁?标准的 http / rest 客户端在收到 404 状态码时不会遵循重定向。如果要重定向客户端,则必须使用 http 状态代码 3xx。请注意,您可能必须将客户端配置为自动跟踪重定向。
  • 标准404确实不做重定向,所以我在web.xml中添加了标签,规定当客户端得到404时,他会被重定向到404 .xhtml。但是如果他从 REST 中得到 404 就不行了……这就是我的问题。
  • 您的应用程序既是web.xml,也是基于注释的。您希望基于注释的部分(称为休息地址)在资源不可用的情况下返回您配置的 404 错误页面,这与重定向无关。那是对的吗?您能否以这种方式重新表述您的问题/问题描述?您的注释 (REST) 部分是否适用于现有资源?
  • 是的,你是对的。所以我要编辑我的问题。是的,注解 (REST) 对现有资源正常工作。

标签: java jax-rs


【解决方案1】:

不太清楚为什么会找到您的其余资源,但对于使用 web.xml 和注释的复杂部署,您需要做更多工作。

您的 RestApplication 类必须扩展 javax.ws.rs.core.Application 以定义 RESTful Web 服务应用程序部署的组件。有关javax.ws.rs.core.Application 的更多详细信息,请参阅http://download.oracle.com/javaee/6/api/javax/ws/rs/core/Application.html 的Javadoc

在您的Application 子类中,您必须根据需要覆盖getClasses()getSingletons() 方法,以返回RESTful Web 服务资源列表。

例如

@ApplicationPath("/rest")
public class RestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(HelloResource.class);
        return s;
    }

}

使用 Hello REST 资源。

@Path("/hello")
public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getHello() {
        return "Hello!";
    }
}

在您的web.xml 中,您必须定义您的 REST 应用程序。 如果需要,可以配置多个。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
id="WebApp_ID" version="3.0">
    <servlet>
        <!-- The servlet name is the full qualified name of your rest application it must be a subclass of java.ws.rs.Application --> 
        <servlet-name>org.example.restexample.RestApplication</servlet-name>
        <!--servlet-class is not needed -->
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <!-- As init parameter pass the full qualified name of the java.ws.rs.Application subclass --> 
            <param-value>org.example.restexample. RestApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- other servlet definitions --> 


    <--servlet mapping --> 

    <error-page>
        <error-code>404</error-code>
        <location>/NotFound.html</location>
    </error-page>
</web-app>

您可以为您的 JaxRS 应用程序指定一个 servlet 映射。如果您这样做,&lt;servlet-mapping&gt; 将优先。

如果资源像 请求“.../rest/foo”,而“.../rest/hello”返回“Hello”。

上面的例子是用 jersey 2.26-b03 和 tomcat 8.5.15 测试的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    相关资源
    最近更新 更多