当属性无效时,我可以在自定义 JSP 标记中使用 JSTL 引发异常吗?
Posted
技术标签:
【中文标题】当属性无效时,我可以在自定义 JSP 标记中使用 JSTL 引发异常吗?【英文标题】:Can I throw exception with JSTL in a custom JSP tag when an attribute is invalid? 【发布时间】: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 块中即可。 谁会捕捉到这个异常? 只要扔就马上注意到问题 【参考方案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()”,然后使用你的自定义标签库,如:<mytaglib:reportError/>
,因为标准核心标签库没有考虑任何人都希望抛出异常。
【讨论】:
【参考方案3】:我只会使用自定义的 EL 函数或标签,系统地抛出异常,或显示带有错误消息的大红色 div,或两者兼而有之
$myFn:illegalState("the type must be odd or even but it is " $type)
【讨论】:
【参考方案4】:我假设您的目标是告知开发人员他们对您的自定义标签的不当使用。正如其他答案中提到的那样,您可能希望以不同的方式处理用户输入错误,因为在 JSP 中引发错误可能(取决于配置)最终会将用户发送到应用程序错误页面。
如果您能够使用 Java 编写标签处理程序,则该规范在 TLD 中包含几个可选元素,可以做到这一点。
-
规范定义了
validator
元素,该元素采用实现javax.servlet.jsp.tagext.TagLibraryValidator
的类。实际上,这使用起来有些复杂,因为它提供了很多灵活性。
规范还定义了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;
【讨论】:
以上是关于当属性无效时,我可以在自定义 JSP 标记中使用 JSTL 引发异常吗?的主要内容,如果未能解决你的问题,请参考以下文章
在自定义 Angular 组件中访问 FormControl
Android Google Map API 自定义标记在自定义标记上带来谷歌地图数据
在自定义 Delphi 组件中实现 Columns.Columns 属性