当属性无效时,我能否使用JSTL在自定义JSP标签中抛出异常?

3

我是一名 JSP 标签开发者。我将一个 type 参数传递给该标签。

代码如下:

<%@ 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>

如果我传递了错误的值,我希望抛出一个异常。当我搜索这个主题时,我只找到了这个。在JSTL中,我不能抛出普通异常吗?


2
我认为在用户界面中不需要抛出异常。只需将错误描述放在否则块中即可。 - KV Prajapati
谁会捕获这个异常? - skaffman
1
立即抛出异常以便及时发现问题。 - Sanghyun Lee
4个回答

2
我决定恢复和编辑一篇被删除的答案,这篇答案看起来部分正确。

You can throw an exception by adding it in a scriptlet like so:

<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>

However, your jsps are supposed to be part of your "view" layer so you should really try to keep your logic (including throwing the exception) in your servlets.

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

1
只需立即通知问题
谁会“注意”?该异常只能被容器捕获,并且会导致一些“500内部服务器错误”页面(或您定义的某个自定义错误页面)。
如果这是您真正想要的,您可以定义一个自定义标记,它将执行“throw new WhateverException()”,然后像这样使用您的自定义标记库:<mytaglib:reportError/>,因为标准核心标记库从未考虑过抛出异常对任何人都是可取的。

1

我会使用自定义的EL函数或标签,它可以系统性地抛出异常,或显示一个带有错误信息的大红色div,或两者兼备。

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

0

我假设你的目标是告知开发人员他们不正确使用了你的自定义标签。正如其他答案所暗示的那样,你应该以不同的方式处理用户输入错误,因为在 JSP 中抛出错误可能会(根据配置)将用户发送到应用程序错误页面。

如果你能够在 Java 中编写标签处理程序,则规范包括 TLD 中的一些可选元素可以实现此功能。

  1. 规范定义了 validator 元素,它接受一个实现 javax.servlet.jsp.tagext.TagLibraryValidator 的类。实际上,这有点复杂,因为它提供了很多灵活性。
  2. 规范还定义了 tei-class,它接受一个扩展 TagExtraInfo 的类。正如 JavaDoc 中所述:
  3. 自定义标记的额外标记信息;此类在标记库描述符文件(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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接