如何在restful服务中捕获或引发Viewable对象内的异常

时间:2012-06-01 17:28:15

标签: java rest jersey

我希望能够在页面名称为PathParam的情况下从restful服务返回特定的jsp页面。部署应用程序后,这些页面将由不同的人员添加和删除。

我相信使用Viewable对象是一个不错的方式(我对更好/更正确的方式持开放态度。)

@GET
@Produces(MediaType.TEXT_HTML)
@Path("{page}") 
public Response showJSP(@PathParam("page") String page) {
    Viewable loadPage = null;

    try {
      loadPage = new Viewable("/" + page, null);
    } catch (Exception e) {
        return Response.status(404).build();
    }

  Response ret = Response.ok(loadPage).build();

//    if (ret.getStatus() == 500){
//          ret = Response.status(404).build();
//      }

 return ret;
}

以上是我的实验性代码,包含我尝试处理错误。

只要页面名称是有效的jsp页面,这就可以正常工作。如果我传入无效页面,我会

500 Internal Server Error

java.io.IOException: The template name, /someWrongFileName, could not be resolved to a fully qualified template name.....

我发现这个错误是在Viewable对象内部生成的,所以它不会抛出异常,当然Response是一个有效的页面,所以检查500状态不起作用。

我可以破解一些我非常肯定是错误的事情,例如,我真的不想为生成的页面和正则表达式输出错误文本。

我希望能够检测到该页面无效,只需返回404。

我是在正确的道路上还是有更好的方法?

如果我走的正确路径,如何检测错误的页面名称?

2 个答案:

答案 0 :(得分:2)

我尝试像你一样抓住错误,但似乎很难。我想这个课程从未打算以这种方式使用。

Viewable接口允许您使用JSP作为可视化应用程序资源表示的方法。通常,资源由您序列化为JSON,XML或传递给Viewable构造函数的POJO表示。

据我所知,你在这里尝试做的事情有点不同。您的资源本身就是JSP,您似乎只想让页面可供客户端使用,而不将任何对象传递给Viewable构造函数。

HTTP 404错误表示无法找到资源。在您的情况下(将JSP视为资源),当JSP的路径不正确时,这正是发生的事情,因此我理解您为什么要使用状态代码。

但是,我认为您尝试使用的界面的创建者对此事有不同的看法。他们没有将JSP视为资源,而是将其视为表示它们的工具。在这里看到视图的构造是完全不同的东西。服务器内部的问题以及应该从客户端隐藏的内容。客户端必须接收带有HTML字符串的响应。如何发生应该无关紧要。在这种情况下,HTTP 500完全可以理解。

如果您只想使用GET请求来获取JSP的内容,您可以忽略Viewable接口甚至Jersey本身。如果您的web.xml设置得当,那么无论如何都应该可以访问这些页面。您不必将JSP名称传递给带注释的方法。只需使用文档本身的路径。自定义404也可以在web.xml中处理。

假设您有一个名为MyApp的项目并部署到路径<host>:<port>/MyApp

使用其网页目录的以下结构。

-Web pages
|-META-INF
|-WEB-INF
|-error
|\-error404.jsp
|-package1
||-ResourceClass
||\-page1.jsp
|-pages
||-plainpage1.jsp
|\-plainpage2.jsp
\-index.jsp

现在,让我们假设web.xml看起来像这样:

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
    <servlet-name>ServletAdaptor</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>ServletAdaptor</servlet-name>
    <url-pattern>/resources/ *</url-pattern>
</servlet-mapping>
<error-page>
    <error-code>404</error-code>
    <location>/err/err404.jsp</location>
</error-page>
<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>

您可以使用Viewable界面显示实际资源的页面。这是应该如何使用接口。 表示资源的HTML表示的方法,而不是资源本身

package package1;

@Path("/")
public class ResourceClass {    

@Path("/POJO/{id}")
@GET
public Response tryToGetBadView(@PathParam("id") String id) {
    MyPOJOClass entity = null;
    //fetch your POJO from database/file/whatever          
    return Response.ok().entity(new Viewable("page1",entity)).build();        
}
}

您可以使用以下路径获取相应的视图:

<host>:<port>/MyApp/resources/POJO/1

虽然能够在没有Jersey Servlet Container的帮助下获得普通的JSP。文件在那里,他们不需要任何其他表示而不是他们自己。 Jersey Servlet容器的路径指定为

<host>:<port>/resources/*

因此,您可以省略容器并从Web Apps文件夹中访问普通文件。图像,CSS和JSP。 像这样:

<host>:<port>/MyApp/pages/plainpage1.jsp

以同样的方式

<host>:<port>/MyApp/index.jsp

甚至是您通常用于构建Viewable对象的页面(不保证它在没有传递POJO的情况下也能正常工作)

<host>:<port>/MyApp/package1/ResourceClass/page1.jsp

对于这些“静态”文件,每次选择不存在页面的名称时,您将获得404。显示的错误页面将是web.xml

中指定的页面

我就是这样做的。使用Jersey来提供简单的JSP似乎是一种过度杀伤并带来不必要的复杂性。如果这不是你的意思,我建议重新考虑设计。

请注意,虽然没有使用Jersey,但仍然可以以您认为RESTful的方式访问页面。

如果您真的想坚持使用您的实验代码,您还可以尝试使用IO API访问Web Pages文件夹中的目录,并手动检查所请求的文件是否存在。它很难看但它可能会起作用。

答案 1 :(得分:2)

我在another post找到了我正在寻找的内容并修改了我的方法。

@GET
@Produces("text/html")
@Path("{page}") 
public void showJSP(@Context HttpServletResponse response,
                    @Context HttpServletRequest request,
                    @PathParam("orderId") String orderId) throws ServletException, IOException {
    request.getRequestDispatcher(page + ".jsp").forward(request, response);
}

这给了我404我正在寻找的所有服务仍然有用。

如果这是'错误'的方式,我仍然愿意接受这些想法,但现在它仍然有效。