學習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>