【问题标题】:Can I throw exception with JSTL in a custom JSP tag when an attribute is invalid?当属性无效时,我可以在自定义 JSP 标记中使用 JSTL 引发异常吗?
【发布时间】:2012-02-09 09:06:56
【问题描述】:

我正在制作一些 JSP 标记。我将类型参数传递给标签。

代码如下:

<%@ attribute name="type" require="true" %>
<c:choose>
    <c:when test="${type eq 'even'}">
        <c:set var="remainder" value="0" />
    </c:when>
    <c:when test="${type eq 'odd'}">
        <c:set var="remainder" value="1" />
    </c:when>
    <c:otherwise>
        <%-- Want to throw exception!! --%>
    </c:otherwise>
</c:choose>

如果我传递了错误的值,我想抛出一个异常。当我搜索这个主题时,我发现了this。我不能在 JSTL 中抛出一个正常的异常吗?

【问题讨论】:

  • 我不认为你真的需要在用户界面中抛出异常。只需将错误描述放在 else 块中即可。
  • 谁会捕捉到这个异常?
  • 只要扔就马上注意到问题

标签: jsp exception jstl custom-tags


【解决方案1】:

我决定恢复和编辑看起来部分正确的a deleted answer

您可以通过将其添加到 scriptlet 中来引发异常,如下所示:

<c:choose>
    <c:when test="${type eq 'even'}">
        <c:set var="remainder" value="0" />
    </c:when>
    <c:when test="${type eq 'odd'}">
        <c:set var="remainder" value="1" />
    </c:when>
    <c:otherwise>
        <% if (true) throw new Exception("Wrong type"); %>
    </c:otherwise>
</c:choose>

但是,您的 jsps 应该是“视图”层的一部分,因此您应该真正尝试将逻辑(包括抛出异常)保留在 servlet 中。

注意if (true) 语句。这是一个技巧,因为如果您只是将异常脚本放入您的代码中,编译器会抱怨“无法访问的代码”。

【讨论】:

    【解决方案2】:

    只要扔就马上注意到问题

    谁会“注意到”?该异常只能被容器捕获,它会导致一些“500 Internal Server Error”页面(或您定义的一些自定义错误页面)。

    如果这是你真正想要的,你可以定义一个自定义标签来执行“抛出新的 WhatException()”,然后使用你的自定义标签库,如:&lt;mytaglib:reportError/&gt;,因为标准核心标签库没有考虑任何人都希望抛出异常。

    【讨论】:

      【解决方案3】:

      我只会使用自定义的 EL 函数或标签,系统地抛出异常,或显示带有错误消息的大红色 div,或两者兼而有之

      ${myFn:illegalState("the type must be odd or even but it is " ${type})}
      

      【讨论】:

        【解决方案4】:

        我假设您的目标是告知开发人员他们对您的自定义标签的不当使用。正如其他答案中提到的那样,您可能希望以不同的方式处理用户输入错误,因为在 JSP 中引发错误可能(取决于配置)最终会将用户发送到应用程序错误页面。

        如果您能够使用 Java 编写标签处理程序,则该规范在 TLD 中包含几个可选元素,可以做到这一点。

        1. 规范定义了validator 元素,该元素采用实现javax.servlet.jsp.tagext.TagLibraryValidator 的类。实际上,这使用起来有些复杂,因为它提供了很多灵活性。
        2. 规范还定义了tei-class,它采用扩展TagExtraInfo 的类。正如 JavaDoc 所指出的:

          自定义标签的额外标签信息;这个类在 标记库描述符文件 (TLD)。必须使用这个类:

          • 如果标签定义了任何脚本变量
          • 如果标签想要提供标签属性的翻译时验证

        根据 JSP 版本,您需要重写 isValid()validate() 方法来处理验证开发人员提供的变量。

        Apache 标签库使用这些来验证他们的一些标签: (https://github.com/javaee/jstl-api/blob/master/impl/src/main/java/org/apache/taglibs/standard/tei/ImportTEI.java)

            public boolean isValid(TagData us) {
                if (Util.isSpecified(us, VAR) && Util.isSpecified(us, VAR_READER))
                    return false;
        
                return true;
            }
        

        或者,如果您使用的是 JSP 2.0,那么实现 validate 会稍微复杂一些,因为它允许返回 ValidationMessage 的数组。 Glassfish 有一个例子:(https://github.com/javaee/glassfish/blob/master/appserver/tests/appserv-tests/devtests/web/jspGetTagLibraryInfos/servlet/taglib/MyTagExtraInfo.java)

            public ValidationMessage[] validate(TagData data) {
                ValidationMessage[] vms = null;
                TagLibraryInfo[] infos =
                    getTagInfo().getTagLibrary().getTagLibraryInfos();
                if (infos.length != 1) {
                    vms = new ValidationMessage[1];
                    vms[0] = new ValidationMessage(null, "Wrong number of tsglibs");
                }
                return vms;
            }
        

        【讨论】:

          猜你喜欢
          • 2015-05-14
          • 2016-09-20
          • 2011-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-21
          相关资源
          最近更新 更多