简体   繁体   中英

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. I have created a dynamic web project and a server project in Eclipse. Both projects have the deployment files(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.

The projects have the following directory structure:

在此处输入图片说明

Should the parameters be defined in the server deployment files?

Edit #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>

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"); throws a NullPointerException .

Edit #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:

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); does not initialize the parameters in the annotations.

Edit #4:

I've managed to run the servlet and retrieve dbURL parameter value. However, now, when launched the application tries to open and gives a 404 Not Found error:

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

I have to manually edit the URL to:

http://localhost:8080/DynamicWebProject1/LoginServlet

in order to run the servlet.

The init() method is now:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM