[英]Java Servlet Deployment Tomcat
Following this question the web.xml deployment file is optional since Java EE 6. I am currently using Java EE 7, Eclipse(kepler) and apache-tomcat-7.0.47 win x64. 从这个问题开始,从Java EE 6开始,web.xml部署文件是可选的。我当前正在使用Java EE 7,Eclipse(kepler)和apache-tomcat-7.0.47 win x64。 I have created a dynamic web project and a server project in Eclipse.
我在Eclipse中创建了一个动态Web项目和一个服务器项目。 Both projects have the deployment files(web.xml, context.xml).
这两个项目都有部署文件(web.xml,context.xml)。
After editing the web.xml in the web project and running a servlet in the context of the server a NullPointerException
is thrown when trying to access any parameter defined in web.xml. 在Web项目中编辑web.xml并在服务器上下文中运行servlet之后,尝试访问web.xml中定义的任何参数时将引发
NullPointerException
。
The projects have the following directory structure: 这些项目具有以下目录结构:
Should the parameters be defined in the server deployment files? 是否应该在服务器部署文件中定义参数?
Edit #1: 编辑#1:
web.xml: web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>LoginExample</display-name>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>dbURL</param-name>
<param-value>jdbc:mysql://localhost/mysql_db</param-value>
</context-param>
<context-param>
<param-name>dbUser</param-name>
<param-value>mysql_user</param-value>
</context-param>
<context-param>
<param-name>dbUserPwd</param-name>
<param-value>mysql_pwd</param-value>
</context-param>
</web-app>
The parameters are accessed here: 可在此处访问参数:
package sebi.first;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet(
description = "Login Servlet",
urlPatterns = { "/LoginServlet" },
initParams = {
@WebInitParam(name = "user", value = "myuser"),
@WebInitParam(name = "password", value = "mypass")
})
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
super.init(config);
//we can create DB connection resource here and set it to Servlet context
System.out.println("BEFORE OUTPUT"); // <== This is displayed in the console
System.out.println("Check the string getServletContext().getInitParameter(\"dbURL\") = " + getServletContext().getInitParameter("dbURL")); // <== NULL pointer exception thrown
if(getServletContext().getInitParameter("dbURL").equals("jdbc:mysql://localhost/mysql_db") &&
getServletContext().getInitParameter("dbUser").equals("mysql_user") &&
getServletContext().getInitParameter("dbUserPwd").equals("mysql_pwd"))
getServletContext().setAttribute("DB_Success", "True");
else throw new ServletException("DB Connection error");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get request parameters for userID and password
String user = request.getParameter("user");
String pwd = request.getParameter("pwd");
//get servlet config init params
String userID = getServletConfig().getInitParameter("user");
String password = getServletConfig().getInitParameter("password");
//logging example
log("User="+user+"::password="+pwd);
if(userID.equals(user) && password.equals(pwd)){
response.sendRedirect("LoginSuccess.jsp");
}else{
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
PrintWriter out= response.getWriter();
out.println("<font color=red>Either user name or password is wrong.</font>");
rd.include(request, response);
}
}
Any parameter I try to access using getServletConfig().getInitParameter("paramName");
我尝试使用
getServletConfig().getInitParameter("paramName");
访问的任何参数getServletConfig().getInitParameter("paramName");
throws a NullPointerException
. 抛出
NullPointerException
。
Edit #2: 编辑#2:
The stack trace thrown is as follows: 引发的堆栈跟踪如下:
type Exception report
message Servlet.init() for servlet sebi.first.LoginServlet threw exception
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Servlet.init() for servlet sebi.first.LoginServlet threw exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
root cause
java.lang.NullPointerException
javax.servlet.GenericServlet.getServletContext(GenericServlet.java:125)
sebi.first.LoginServlet.init(LoginServlet.java:33)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
It seems that parameters defined within the annotations throw the same exception as well. 注释中定义的参数似乎也抛出相同的异常。
Edit #3: 编辑#3:
I've written a short snippet suggestion: 我写了一段简短的建议:
@WebServlet(description = "Test Parameters", urlPatterns = { "/TestParam",
"/TestParam.do" }, initParams = {
@WebInitParam(name = "first", value = "FIRST"),
@WebInitParam(name = "second", value = "SECOND") })
public class TestParam extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
super.init(config);
// we can create DB connection resource here and set it to Servlet
// context
System.out.println("BEFORE OUTPUT");
System.out.println("First parameter = "
+ config.getServletContext().getInitParameter("first"));
System.out.println("Second parameter = "
+ config.getServletContext().getInitParameter("second"));
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.getOutputStream().println("No");
}
}
Now no exceptions are thrown, but the parameter values are both null which suggests that super(config); 现在不会引发任何异常,但是参数值都为null,这表明super(config); does not initialize the parameters in the annotations.
不初始化注释中的参数。
Edit #4: 编辑#4:
I've managed to run the servlet and retrieve dbURL parameter value. 我已经设法运行servlet并检索dbURL参数值。 However, now, when launched the application tries to open and gives a 404 Not Found error:
但是,现在,启动后,应用程序尝试打开并给出404 Not Found错误:
http://localhost:8080/DynamicWebProject1/servlet/sebi.first.LoginServlet
I have to manually edit the URL to: 我必须手动将URL编辑为:
http://localhost:8080/DynamicWebProject1/LoginServlet
in order to run the servlet. 为了运行servlet。
The init() method is now: 现在,init()方法为:
public void init(ServletConfig config) throws ServletException {
super.init(config);
//we can create DB connection resource here and set it to Servlet context
System.out.println("BEFORE OUTPUT");
System.out.println("Check the string getServletContext().getInitParameter(\"dbURL\") = " + config.getServletContext().getInitParameter("dbURL"));
if(config.getServletContext().getInitParameter("dbURL").equals("jdbc:mysql://localhost:3306/mysql_db") &&
config.getServletContext().getInitParameter("dbUser").equals("mysql_user") &&
config.getServletContext().getInitParameter("dbUserPwd").equals("mysql_pwd"))
config.getServletContext().setAttribute("DB_Success", "True");
else throw new ServletException("DB Connection error");
}
Still, I am not able to access parameters defined in annotations. 不过,我仍然无法访问注释中定义的参数。
If you need init params for the Servlet you should use the ServletConfig
object passed to the init
method ( ServletConfig#getInitParameter(String)
) and configure the Servlet like so: 如果您需要Servlet的初始化参数,则应使用传递给
init
方法的ServletConfig
对象( ServletConfig#getInitParameter(String)
)并像下面这样配置Servlet:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
<init-param>
<param-name>dbURL</param-name>
<param-value>jdbc:mysql://localhost/mysql_db</param-value>
</init-param>
<init-param>
<param-name>dbUser</param-name>
<param-value>mysql_user</param-value>
</init-param>
<init-param>
<param-name>dbUserPwd</param-name>
<param-value>mysql_pwd</param-value>
</init-param>
</servlet>
您将throws ServletException
这样的异常,从而throws ServletException
为何不try
使用catch(Exception e){e.printStackTrace();}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.