【问题标题】:Java Servlet Deployment TomcatJava Servlet 部署 Tomcat
【发布时间】:2014-01-19 00:15:14
【问题描述】:

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

项目的目录结构如下:

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

编辑#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:

我写了一个简短的 sn-p 建议:

@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

我必须手动编辑网址:

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

不过,我无法访问注释中定义的参数。

【问题讨论】:

  • 您尝试访问的参数是什么?你能发布你的 web.xml 文件吗?
  • 我很好奇为什么Tomcat 7下还有一个web.xml文件,可能和问题有关?
  • 该文件是随项目创建的。我已经尝试编辑它们(来自两个项目),以便每个条目具有相同的条目,但问题仍然存在。
  • jdbc:mysql://localhost:PORT_NO/mysql_db ,你没有添加端口号。 mysql.可能是个问题。
  • 我已经添加了端口号(3306),但是,参数没有被解析,每个参数都从以下行开始抛出一个NULL指针异常:System.out.println("检查字符串getServletContext().getInitParameter(\"dbURL\") = " + getServletContext().getInitParameter("dbURL"));

标签: java eclipse jsp tomcat servlets


【解决方案1】:

如果您需要 Servlet 的初始化参数,您应该使用传递给 init 方法 (ServletConfig#getInitParameter(String)) 的 ServletConfig 对象并像这样配置 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>

【讨论】:

  • 但我不得不承认这不是的答案。 OP 的代码也应该可以正常工作。可能存在一些部署不一致问题,这在 Eclipse 中很常见。
  • 不,GenericServlet:125(即对 getServletContext 的调用)会尝试使用为空的 read the servlet config
  • super.init(config); ...不是;)
【解决方案2】:

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

【讨论】:

  • 这不是答案,您应该将其作为评论留下。
  • 什么?那是我的反对意见……我也在考虑将其标记为垃圾邮件。请再次阅读问题以查看 OP 的要求。
猜你喜欢
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 2017-02-01
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多