Java Servlet部署Tomcat

时间:2014-01-01 10:52:46

标签: java eclipse jsp tomcat servlets

this提问之后,web.xml部署文件是可选的,因为Java EE 6.我目前正在使用Java EE 7,Eclipse(kepler)和apache-tomcat-7.0.47 win x64。我在Eclipse中创建了一个动态Web项目和一个服务器项目。这两个项目都有部署文件(web.xml,context.xml)。

在Web项目中编辑web.xml并在服务器上下文中运行servlet时,尝试访问web.xml中定义的任何参数时会引发NullPointerException

项目具有以下目录结构:

enter image description here

是否应在服务器部署文件中定义参数?

编辑#1:

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

这里可以访问参数:

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

    }

}

我尝试使用getServletConfig().getInitParameter("paramName");访问的任何参数都会引发NullPointerException

编辑#2:

抛出的堆栈跟踪如下:

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)

注释中定义的参数似乎也会抛出相同的异常。

编辑#3:

我写了一个简短的片段建议:

@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");
}
}

现在没有抛出异常,但参数值都为null,这表明super(config);不会初始化注释中的参数。

编辑#4:

我设法运行servlet并检索dbURL参数值。但是,现在,在启动时,应用程序尝试打开并给出404 Not Found错误:

http://localhost:8080/DynamicWebProject1/servlet/sebi.first.LoginServlet

我必须手动将URL编辑为:

http://localhost:8080/DynamicWebProject1/LoginServlet

以运行servlet。

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");
}

但是,我无法访问注释中定义的参数。

2 个答案:

答案 0 :(得分:0)

如果你需要Servlet的init参数,你应该使用传递给ServletConfig方法(init)的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>

答案 1 :(得分:-2)

您正在抛出这样的例外throws ServletException为什么不将try包含在catch(Exception e){e.printStackTrace();}