【问题标题】:Is it possible to use a JSP as a template for a servlet?是否可以使用 JSP 作为 servlet 的模板?
【发布时间】:2010-12-16 10:36:22
【问题描述】:

我一直在我正在构建的 Web 应用程序中混合 JSP 和 Servlet,我开始发现我的更复杂的 JSP 最终包含大量代码,这些代码与所有 MVC 课程背道而驰已经被我撞到了。我知道我可以通过转发到 JSP 来做到这一点,但这似乎是一个愚蠢的 hack。

我想做的是使用 servlet 进行处理,然后将一组值发送到 JSP 以呈现 HTML 并返回响应。大致如下:

public class MyServlet extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws IOException {

         // ... Do some processing

         resp.getWriter.print(renderJSP("mypage.jsp", values));

    }

}

我一直在浏览 Sun 的文档,发现:http://java.sun.com/developer/technicalArticles/javaserverpages/servlets_jsp/ 看起来 JSP 模型 2 架构正是我想要实现的,但我找不到如何设置它的示例。由于技术原因,我不能使用像 Struts 这样的更高级的模板框架之一。

这是可能的还是失败的原因?

【问题讨论】:

  • “由于技术原因,我不能使用像 Struts 这样更高级的模板框架之一。” - 所以你基本上要为你的应用重新实现它......
  • 我知道这是一个幼稚的说法,但这真的不像我在重新发明整个框架。我只是在寻找一种将两种现有技术结合在一起的方法,在我看来,这是一个非常明显的用例。

标签: java jsp servlets web-applications


【解决方案1】:

您将转发到 JSP 描述为一种 hack,但实际上,这正是 MVC 框架所做的(至少是 Spring MVC 和 Struts)。

“模型”是 servlet 填充的请求属性;然后 JSP 只是检索它们以显示。您可以像 Spring MVC 那样将其包装在“ModelAndView”中,但实际上就是这样。

您可以对 JSP 进行更复杂的处理,当然,解析请求参数、会话属性或 servlet 上下文(“全局”)属性。我发现,一般来说,让前端控制器/servlet 将所有这些编组到请求属性中并让页面从它​​们中提取出来会更干净。如果您使用的是 JSTL,那么请求和会话之间的区别会更加模糊。

【讨论】:

  • 绝对正确。我已经用 spring 完成了大约 4 个大小合适的 web 应用程序,这绝对不是一个 hack,servlet(或在 spring 中,控制器)设置视图的所有数据,并且 JSP 仅包含用于显示提供给的数据的逻辑它由控制器。它工作得很好,而且真的很容易维护,你肯定想走这条路,它不是黑客。
【解决方案2】:

将 Java 对象放入 Request/Response/Session 并在您的 servlet 中使用 javax.servlet.RequestDispatcher,类似这样:

RequestDispatcher dispatcher = request.getRequestDispatcher("/test.jsp");
dispatcher.forward(request,response);

转发是服务器端,并且目标 servlet/JSP 接收与原始 servlet/JSP 相同的请求/响应对象。因此,您可以使用request.setAttribute() 在它们之间传递数据。

另一种选择是使用response.sendRedirect(String location),它是客户端(此方法向客户端发送临时重定向响应),因此位置 URL 接收来自客户端的新请求,并且传递数据的唯一方法是通过会话或使用网络参数(url?name=value)。

这基本上是 MVC 框架所做的(不,这不是 hack)。

【讨论】:

  • dispatcher.forward() 实际上是向客户端发送 302 还是它在服务器端处理它?我想我的 HTML 术语可能超载了。
  • 我已经更新了我的答案以涵盖两种情况(服务器端和客户端)
【解决方案3】:

将对象放入请求中,将请求转发到jsp页面,然后使用jsp中的对象来渲染响应。

在您的 servlet 中,

MyObject obj = ... //build somehow
request.setAttribute("myObject", obj);
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/my.jsp");
rd.forward(request, response);

如果不应直接从 URL 访问结果 JSP,则应将其隐藏在 WEB-INF 目录中,只能通过 forward 指令访问它。

那么在你的jsp上就可以了,

<% MyObject obj = (MyObject) request.getAttribute("myObject"); %> 

检索对象并根据需要使用它。

正如其他人所建议的那样,最终学习使用JSTL 或者像Spring MVC 这样的MVC 框架将是一个好主意。教程可以在here找到。

【讨论】:

  • rd.forward 是否将 302 发送回客户端,还是在服务器端全部处理?我可能只是混淆了我的术语。
  • @Sean Lynch - 转发目录在服务器端。这就是为什么您可以使用它访问 WEB-INF 目录中的 JSP 页面。
猜你喜欢
  • 1970-01-01
  • 2014-12-13
  • 2010-10-13
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 2013-09-23
相关资源
最近更新 更多