如何在 jsp 简单标记中设置/检索 applicationScope 属性?

2 java jsp servlets

我正在练习Head First Servlets and JSP书中的示例。

书中有一个例子,讨论简单标签创建动态 html 选择标签。如需参考,请参阅页码:542。

我收到以下异常。

org.apache.jasper.JasperException: java.lang.NullPointerException

我不知道如何设置/传递optionList属性值到标签处理程序的设置方法。我认为这就是为什么我得到NullPointerException.There is no Problem with the tld.

选择啤酒.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="my" uri="http://example.com/tags/forms" %>
<!DOCTYPE html>
<html>
<head>
<title>Select Beer</title>
</head>
<body>
<form action="select.do" method="POST">
<p>Select Beer Characteristics: </p>
Color:
<my:select optionList="${applicationScope.colorList}" name="color" size="1"/>
<br><br>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

标记处理程序代码:

public class SelectTagHandler extends SimpleTagSupport {
private String name;
private String size;
private String[] optionList;
private static final String ATTR_TEMPLATE = "%s='%s'";
private static final String OPTION_TEMPLATE = "<option value='1$s'>%1$s</option>";

public void setName(String name) {
    this.name = name;
}

public void setSize(String size) {
    this.size = size;
}

public void setOptionList(String[] optionList) {
   this.optionList = optionList;
}

@Override
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.print("<select");
out.print(String.format(ATTR_TEMPLATE, "name", this.name));
out.print(String.format(ATTR_TEMPLATE, "size", this.size));
out.println('>');

for (Object option : this.optionList) {
String optionTag = String.format(OPTION_TEMPLATE, option.toString());
out.println(optionTag);
}
}
}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪

18:38:34,039 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/jee_war_exploded].[jsp]] (http--127.0.0.1-8000-1) Servlet.service() for servlet jsp threw exception: java.lang.NullPointerException
    at com.jstl.select.SelectTagHandler.doTag(SelectTagHandler.java:40) [classes:]
    at org.apache.jsp.select_002dbeer_jsp._jspx_meth_my_005fselect_005f0(select_002dbeer_jsp.java:101)
    at org.apache.jsp.select_002dbeer_jsp._jspService(select_002dbeer_jsp.java:68)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) [jbossweb-7.0.13.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369) [jbossweb-7.0.13.Final.jar:]
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:326) [jbossweb-7.0.13.Final.jar:]
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:253) [jbossweb-7.0.13.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 5

您的标记处理程序在optionList数组上循环,默认情况下该数组为空。因此,如果您不将此数组设置为非空值,您的标记将会失败。

您正在尝试使用设置此值

<my:select optionList="${applicationScope.colorList}" name="color" size="1"/>
Run Code Online (Sandbox Code Playgroud)

因此,这将从 servlet 上下文中检索属性colorList并将其设置在标记处理程序中。

为此,您需要在 servlet 上下文中拥有一个colorListtype 的attribute 。String[]因此,在执行 JSP 之前,必须先执行以下代码行:

servletContext.setAttribute("colorList", someNonNullStringArray);
Run Code Online (Sandbox Code Playgroud)

代码行应该放置在哪里取决于您和您的要求。由于它对于应用程序来说是全局的,因此将其放入 ServletContextListener 中(在部署应用程序时调用)是有意义的。但为了进行测试,您还可以使用在 JSP 之前调用的 servlet。servlet 上下文可从 servlet 请求获得:

ServletContext servletContext = request.getServletContext();
Run Code Online (Sandbox Code Playgroud)