我希望能够在页面名称为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。
我是在正确的道路上还是有更好的方法?
如果我走的正确路径,如何检测错误的页面名称?
答案 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我正在寻找的所有服务仍然有用。
如果这是'错误'的方式,我仍然愿意接受这些想法,但现在它仍然有效。