学习Servlet时碰到的一个bug。
Connected to server
[2017-01-08 04:40:33,100] Artifact jspRun:war exploded: Artifact is being deployed, please wait...
08-Jan-2017 16:40:33.570 严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/Servlet]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441)
说说解决的思路:
因为不记得对项目做了哪些更改,所以
重新配置一次Servlet环境,没有出现任何问题。
说明我们Tomcat与Intellij是没有问题的。
那么问题只能出现在:
1、代码问题。
2、当前项目属性设置问题。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; /** * Created by N3verL4nd on 2017/1/4. */ @WebServlet(name = "testServlet", urlPatterns = {"test.do"}) public class testServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>TEST</title>"); out.println("</head>"); out.println("<body>"); out.println(request.getRequestURI() + "<br />"); out.println(request.getContextPath() + "<br />"); out.println(request.getServletPath() + "<br />"); Enumeration<String> names = request.getHeaderNames(); while (names.hasMoreElements()){ String name = names.nextElement(); out.println(name + ":" + request.getHeader(name) + "<br />"); } out.println("</body>"); out.println("</html>"); out.close(); } }以上是测试代码,经检查是
@WebServlet(name = "testServlet", urlPatterns = {"test.do"})
使用出错。
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
public @interface WebServlet
This annotation is used to declare the configuration of an
Servlet . If the name attribute is not defined, the fully qualified name of the class is used. At least one URL pattern MUST be declared in either the value or urlPattern attribute of the annotation, but not both.The value attribute is recommended for use when the URL pattern is the only attribute being set, otherwise the urlPattern attribute should be used.The class on which this annotation is declared MUST extend HttpServlet . E.g. @WebServlet("/path")} E.g. @WebServlet(name="TestServlet", urlPatterns={"/path", "/alt"})
|
@WebServlet有很多的属性:
asyncSupported:声明Servlet是否支持异步操作模式。
description: Servlet的描述。
displayName: Servlet的显示名称。
initParams: Servlet的init参数。
name: Servlet的名称。
urlPatterns: Servlet的访问URL。
value: Servlet的访问URL。
Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。
1.完全匹配 要求以/开始,名称与url一致.
2.使用通配符 *
3.目录匹配 以/开始,以*结束.
4.扩展名匹配. 不能以/开始,以*.xxx对束
参考:
http://www.cnblogs.com/fangjian0423/p/servletContainer-tomcat-urlPattern.html
详细解释:
@WebServlet
@WebServlet 用于将一个类声明为 Servlet,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。该注解具有下表给出的一些常用属性(以下所有属性均为可选属性,但是 vlaue 或者 urlPatterns 通常是必需的,且二者不能共存,如果同时指定,通常是忽略 value 的取值):
表 1. @WebServlet 主要属性列表
属性名 | 类型 | 描述 |
---|---|---|
name | String | 指定 Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 |
value | String[] | 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于 <url-pattern> 标签。 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 <load-on-startup> 标签。 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于 <init-param> 标签。 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于 <async-supported> 标签。 |
description | String | 该 Servlet 的描述信息,等价于 <description> 标签。 |
displayName | String | 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name> 标签。 |
下面是一个简单的示例:
@WebServlet(urlPatterns = {"/simple"}, asyncSupported = true, loadOnStartup = -1, name = "SimpleServlet", displayName = "ss", initParams = {@WebInitParam(name = "username", value = "tom")} ) public class SimpleServlet extends HttpServlet{ … }
如此配置之后,就可以不必在 web.xml 中配置相应的 <servlet> 和 <servlet-mapping> 元素了,容器会在部署时根据指定的属性将该类发布为 Servlet。它的等价的 web.xml 配置形式如下:
<servlet> <display-name>ss</display-name> <servlet-name>SimpleServlet</servlet-name> <servlet-class>footmark.servlet.SimpleServlet</servlet-class> <load-on-startup>-1</load-on-startup> <async-supported>true</async-supported> <init-param> <param-name>username</param-name> <param-value>tom</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>SimpleServlet</servlet-name> <url-pattern>/simple</url-pattern> </servlet-mapping>