2

给定页面名称作为 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 对象内部生成的,因此它不会引发异常,并且响应当然是一个有效页面,因此检查 500 状态不起作用。

我可以破解一些我很确定是错误的事情,例如,我真的不想为生成的页面和正则表达式添加错误文本。

我希望能够检测到页面无效并简单地返回 404。

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

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

4

2 回答 2

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 文件夹中的目录并手动检查请求的文件是否存在。这会很丑陋,但它可能会起作用。

于 2012-06-01T19:14:13.207 回答
2

我在另一篇文章中找到了我正在寻找的内容,并在下面修改了我的方法。

@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,我的所有服务仍然有效。

如果这是执行此操作的“错误”方式,我仍然愿意接受想法,但现在它有效。

于 2012-06-05T22:10:37.770 回答