【问题标题】:jsp:forward in Java without using JSP tag?jsp:在Java中转发而不使用JSP标签?
【发布时间】:2010-09-19 16:51:51
【问题描述】:

我可以在 块中使用与 等效的纯 Java 吗?

例如,我目前有一个类似这样的 JSP 页面:

<%
    String errorMessage = SomeClass.getInstance().doSomething();
    if (errorMessage != null) {
        session.setAttribute("error", errorMessage);
%>
<jsp:forward page="error.jsp" />
<%
    } else {
        String url = response.encodeRedirectURL("index.jsp");
        response.sendRedirect(url);
    }
%>

必须打破 块才能使用 jsp:forward 是丑陋的,并且由于缩进等原因使其更难阅读。

那么,我可以在Java代码中不使用JSP标签进行转发吗?

这样的事情会很理想:

<%
    String errorMessage = SomeClass.getInstance().doSomething();
    if (errorMessage != null) {
        session.setAttribute("error", errorMessage);
        someObject.forward("error.jsp");
    } else {
        String url = response.encodeRedirectURL("index.jsp");
        response.sendRedirect(url);
    }
%>

【问题讨论】:

  • 随着时间的推移,正是代码的分解使脚本变得无法维护。这就是为什么首先要使用标记库和 JSTL 的原因。与 some text other text more text 相比,更容易将其视为类似于 HTML。

标签: java jsp jsp-tags forward


【解决方案1】:

一个简单的方法:

<%@page errorPage="Error.jsp" %>

<%
 String errorMessage = SomeClass.getInstance().doSomething();
 if (errorMessage != null) {
       throw new Exception(errorMessage); // Better throw the exception from doSomething()
 }
 pageContext.forward("index.jsp");
%>


Error.jsp
.........
<%@ page isErrorPage='true' %>
<%
out.print("Error!!!");  
out.print(exception.getMessage());
%>

更好的方法:

从 servlet 调用 doSomething()。 在 web.xml 中设置你的错误页面

<error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/WEB-INF/jsp/Error.jsp</location>
</error-page>

【讨论】:

  • 就个人而言——这完全是个人偏好,也许——我认为在 JSP 中进行流控制比使用 JSP、servlet 和 web.xml 设置的组合更容易。这句话说明了原因:如果我都在 JSP 中做,那么它就在一个地方,而不是三个。
【解决方案2】:

如果可以的话,你真的应该尽量避免使用脚本,而且在你的情况下,你正在做的很多事情都可以用 JSTL 代码代替。您的示例的以下替换更简洁,IMO:

<%
  // Consider moving to a servlet or controller/action class
  String errorMessage = SomeClass.getInstance().doSomething();
  pageContext.setAttribute("errorMessage", errorMessage);
%>
<c:choose>
  <c:when test="${not empty errorMessage}">
    <c:set var="error" scope="session" value="${errorMessage}" />
    <jsp:forward page="error.jsp" />
  </c:when>
  <c:otherwise>
    <c:redirect url="index.jsp" />
  </c:otherwise>
</c:choose>

理想情况下,您应该修改 error.jsp,这样甚至不需要在会话中设置错误消息,但我不想过多地更改您的设计。

【讨论】:

  • 您能否在回答中解释为什么应该避免使用 scriptlet 而不是 JSTL?
  • 我一直不清楚 JSTL 相对于普通 scriptlet 的优势是什么。我看到讨论说这允许非程序员创建动态网页,因为您不必了解 Java。但实际上,只要看看上面的例子:这怎么不是“编程”?当然,它不是 Java,但从任何合理的定义来看,它都是一种编程语言。因此,您可以学习和使用 Java 并学习和使用另一种语言,而不是学习和使用 Java。除了增加你必须学习的量之外,还能获得什么?
  • 我和scriptlet 的人在一起。它的代码更少,避免了笨拙的&lt;c:when&gt; 语法,而且速度更快,因为when 中的EL 表达式每次运行时都会被解析为字符串,而java 代码会被编译。
  • @Jay 等人,您确实提出了一个好观点。在这种情况下,JSP 只是被用作(IMO,被滥用)作为一种编程语言,因此它并不重要。然而,IMO,JSP 应该严格用作模板引擎,只有表示逻辑(即没有控制器逻辑,这就是我们在这里所做的,或者更糟糕的是,业务逻辑)。
  • 我认为“JSP 作为一种编程语言”与“JSP 作为具有 servlet 或任何业务逻辑的模板引擎”的双方都有很好的论据。 (而且我认为反对 JSP 作为一种编程语言的最佳论点是:迟早,您会发现它不够用,无论如何都必须做其他事情。那么为什么不早点做并保持一致呢?)但我真的没有看到JSTL 的价值。它只是另一种需要学习的编程语言,而且在这方面非常薄弱。
【解决方案3】:

您要查找的someObjectpageContext

这个对象是在JSP中隐式定义的,所以你可以这样使用它:

pageContext.forward("<some relative jsp>");

【讨论】:

  • 好电话!这比显式获取调度程序更干净。
  • 我认为你应该放一个«return;»转发后,否则页面将继续运行并产生错误(非法状态)。我猜标签会自动为你做这件事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
相关资源
最近更新 更多