我知道这个问题已被问过一百万次,而且有500万个答案 - 一些或者说非常有用。这些都没有解决这个问题。
我的目标与许多其他人类似 - 我想在Web应用程序运行时环境中访问文件 - 图像,svgfiles,模板等。如果我只是硬连接目录路径,我可以使它工作。但是,我想让我的servlet可移植并使用相对引用来访问这些资源 - 如果我没有其他原因我在Windows中开发并在Linux中部署。
基本问题是getServletContext()为null,我无法确定原因。
以下是错误消息,生成它的代码,以及环境详细信息。在开发和生产中产生相同的错误。如有要求,我将很乐意提供任何其他详细信息。
请解释我需要做些什么来实现这项工作?我会永远感激。此致
SEVERE: Servlet.service() for servlet [jsp] in context with path [/HelloWorld] threw exception [An exception occurred processing JSP page /hello.jsp at line 19
16: <title>Hello World</title>
17: </head>
18: <body>
19: <%=wtGreet.getGreeting()%>
20: </body>
21: </html>
Stacktrace:] with root cause
java.lang.NullPointerException
at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:125)
at HelloWorld.Greeting.getGreeting(Greeting.java:23)
at org.apache.jsp.hello_jsp._jspService(hello_jsp.java:91)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
HelloWorld应用程序正常运行 - 产生意外错误 - 与真实错误完全相同。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF 8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<jsp:useBean id="wtGreet" scope="page"
class="HelloWorld.Greeting">
<jsp:setProperty name="wtGreet" property="who" value="World"/>
<jsp:setProperty name="wtGreet" property="greet" value="Hello"/>
</jsp:useBean>
<jsp:setProperty name="wtGreet" property="*"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Hello World</title>
</head>
<body>
<%=wtGreet.getGreeting()%>
</body>
</html>
然后是jsp调用的Servlet
package HelloWorld;
import javax.servlet.http.HttpServlet;
public class Greeting extends HttpServlet {
private static final long serialVersionUID = 1298516959968350334L;
private String who;
private String greet;
public void setWho(String who) {
this.who = who;
}
public void setGreet(String greet) {
this.greet = greet;
}
public String getGreeting() {
System.out.println("getServletContext() == null :" + getServletContext().getContextPath());
return "<p>" + this.greet + " " + this.who + "</P>";
}
}
开发环境 视窗 Eclipse JEE 阿帕奇 雄猫7 JRE 7
生产环境 Linux的 阿帕奇 雄猫7 JRE 8
答案 0 :(得分:2)
基于堆栈跟踪的最后一个元素
at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:125)
调用方法getServletContext()
,异常发生在类125
的行javax.servlet.GenericServlet
中。
如果getServletContext()
返回null
,那么最后一个堆栈跟踪元素将是
at HelloWorld.Greeting.getGreeting(Greeting.java:23)
根据javax.servlet.GenericServlet
的{{3}},方法getServletConfig()
是返回null
的方法,即您未配置servlet。
这可能是因为你(在你的jsp
中使用servlet作为bean)<jsp:useBean id="wtGreet" scope="page" class="HelloWorld.Greeting">
并且该servlet未正确初始化。
Servlet不应该像这样使用。您可能希望使用简单的code并使其具有方法getGreeting()
。
要获取jsp中的ServletContext
,您可以使用隐式对象application
,请参阅JavaBean了解jsp中的其他可用隐式对象。
答案 1 :(得分:0)
即使最终的解决方案是实现模型2模式(我将在完成时包括),但对于所提出的问题,有一个很好的工作答案。感谢A4L展示道路。
根据jsp引擎将jsp编译为servlet并将其加载到servlet引擎的理解,jsp隐式对象可用于访问实例化的javax.servlet对象。
HelloWorld示例更改如下: 1)删除import javax.servlet.http.HttpServlet;并扩展了HttpServlet,因为它什么都不做。 2)添加ServletContext类型的属性,并使用jsp页面中的setter填充该属性。
通过jsp隐式对象,bean可以使用任何可用的对象。
JSP
{<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<jsp:useBean id="wtGreet" scope="page"
class="HelloWorld.Greeting">
<jsp:setProperty name="wtGreet" property="who" value="World"/>
<jsp:setProperty name="wtGreet" property="greet" value="Hello"/>
</jsp:useBean>
<jsp:setProperty name="wtGreet" property="*"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
</head>
<body>
<%wtGreet.setSc(application.getContext("/HelloWorld"));%>
<%=wtGreet.getGreeting()%>
</body>
</html>}
Bean
package HelloWorld;
import javax.servlet.ServletContext;
public class Greeting {
private String who;
private String greet;
private ServletContext sc;
public void setSc(ServletContext sc) {
this.sc = sc;
}
public void setWho(String who) {
this.who = who;
}
public void setGreet(String greet) {
this.greet = greet;
}
public String getGreeting() {
return "<p>" + this.greet + " " + this.who + " from \"Context Path\" " + sc.getContextPath() + "</P>";
}
}