JavaWeb之Servlet一
Posted jyliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb之Servlet一相关的知识,希望对你有一定的参考价值。
时间:2019.03.27
主机环境:MacBookPro
Servlet
1. Servlet简介
-
Servlet是JavaWeb的三大组件之一,属于动态资源
-
Servlet的功能
-
接受请求数据
-
处理请求:每个Servlet都是唯一的,能处理的请求都是不同的
-
完成响应
-
-
Servlet需要我们自己编写
2. 实现Servlet的方式(三种)
-
实现javax.servlet.Servlet接口
-
继承javax.servlet.GenericServlet类
-
继承javax.servlet.http.HttpServlet类,它是GenericServlet的子类
3. Servlet接口
-
接口中的方法,生命周期方法是Tomcat自动调用的方法
publicclassMyServletimplementsServlet{ //是生命周期方法 //会在Servlet对象被创建后马上执行,并只执行一次 publicvoidinit(ServletConfigservletConfig) throwsServletException; //可以用来获取Servlet的配置信息 publicServletConfiggetServletConfig(); ? //是生命周期方法 //会被调用多次 //每次处理请求都会被调用 publicvoidservice(ServletRequestservletRequest, ServletResponseservletResponse) throwsServletException, IOException; //可以获取Servlet的信息 publicStringgetServletInfo(); //是生命周期方法 //会在Servlet被销毁之前调用,并且只会被调用一次 //该方法不能销毁Servlet publicvoiddestroy(); } ?
-
在web.xml文件中配置Servlet
<servlet> <!--xxx可以随便写--> <servlet-name>xxx</servlet-name> <servlet-class>servlet.MyServlet</servlet-class> </servlet> ? <servlet-mapping> <servlet-name>xxx</servlet-name> <!--必须以/开头,后面随便写--> <url-pattern>/MyServlet</url-pattern> </servlet-mapping>
-
ServletConfig接口
-
一个ServletConfig对象对应一段web.xml中的Servlet配置信息
-
API:
-
String getServletName():获取<servlet.name>的内容
-
ServletContext getServletContext():获取Servlet上下文的对象
-
String getInitParament():通过名称获取指定初始化参数的值
-
Enumeration getInitParamentName():获取所有初始化参数的名称
-
-
<servlet> <servlet-name>One</servlet-name> <servlet-class>cn.itcast.servlet.OneServlet</servlet-class> <init-param> <param-name>paramName1</param-name> <param-value>paramValue1</param-value> </init-param> <init-param> <param-name>paramName2</param-name> <param-value>paramValue2</param-value> </init-param> </servlet>
4. GenericServlet类
-
GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet。
下面是GenericServlet类的源代码
public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { private static final long serialVersionUID = 1L; private transient ServletConfig config; public GenericServlet() {} @Override public void destroy() {} @Override public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return getServletConfig().getInitParameterNames(); } @Override public ServletConfig getServletConfig() { return config; } @Override public ServletContext getServletContext() { return getServletConfig().getServletContext(); } @Override public String getServletInfo() { return ""; } @Override public void init (ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init () throws ServletException {} public void log(String msg) { getServletContext().log(getServletName() + ": " + msg); } public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t); } @Override public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; @Override public String getServletName() { return config.getServletName(); } }
-
init()方法
-
init()方法是用来在继承GenericServlet类时,解决想要覆盖init(ServletConfig config)方法忘记给config赋值的问题。此时,只需要覆盖init()方法即可。
-
init()方法不是生命周期方法,但想要在构造Servlet时让Tomcat调用该方法,需要在init(ServletConfig config)中调用init()方法
-
-
GenericServlet实现了所有ServletConfig的方法。
5. HttpServlet类
-
HttpServlet是GenericServlet的子类,它提供了对HTTP请求的特殊支持,所以通常我们都会通过继承HttpServlet来完成自定义的Servlet。
-
HttpServlet覆盖了service()方法
-
HttpServlet中有两个service()方法,一个service(ServletRequest,ServletResponse),另一个为service(HttpServletRequest,HttpServletResponse),前者为覆盖,后者不是覆盖。
-
service(ServletRequest,ServletResponse)是生命周期方法,由Tomcat自动调用,在该方法中
-
首先对两个参数强制转换,将类型转换为Http协议相关的类型,
-
再调用service(HttpServletRequest,HttpServletResponse)方法,
-
该方法会通过request得到当前请求的请求方式(GET或POST),
-
再根据请求方式调用相应的doGet()和doPost()方法。
-
-
所以,不用重写service()方法,只需要重写doGet()和doPost()方法。如果没有覆盖doGet()和doPost()方法,并且被调用了,会出现405。
-
6. Servlet细节
-
Servlet只有一个实例对象,就有可能会现时出一个Servlet同时处理多个请求
Servlet不是线程安全的。这说明Servlet的工作效率很高,但也存在线程安全问题!所以我们不应该在Servlet中随便创建成员变量,因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作。
做到以下几点:
-
不要在Servlet中创建成员,创建局部变量即可
-
可以创建无状态成员,即只声明
-
可以创建有状态的成员,但状态必须为只读的
-
-
默认情况下,服务器会在某个Servlet第一次收到请求时创建它。也可以在web.xml中对Servlet进行配置,使服务器启动时就创建Servlet。
<servlet> <servlet-name>hello1</servlet-name> <servlet-class>cn.itcast.servlet.Hello1Servlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hello1</servlet-name> <url-pattern>/hello1</url-pattern> </servlet-mapping> ? <servlet> <servlet-name>hello2</servlet-name> <servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hello2</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping>
在<load-on-startup>中,给出一个非负整数。值小的先被创建,即hello1先创建,hello2后创建。
-
<url-pattern>
-
用来指定Servlet的访问路径,可以在<servlet-maping>中有多个
-
可以使用通配符*,通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符
路径匹配:<url-pattern>/servlet/*</url-pattern>,可以匹配/servlet/a、/servlet/b等
扩展名匹配:<url-pattern>*.do</url-pattern>,可以匹配/abc/def/ghi.do、/a.do等
啥都匹配:<url-pattern>/*</url-pattern>,可以匹配所有url
-
-
web.xml文件的“继承”
-
每一个JavaWeb应用都有一个web.xml,都“继承”conf/web.xml
-
<?xmlversion="1.0" encoding="ISO-8859-1"?> ? <web-appxmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <servlet> <servlet-name>default</servlet-name><!--他的优先级最低,如果请求没人处理,那么它就会来处理,显示404--> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> ? <servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> ? <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> <!--没有url能匹配上,就会匹配这个--> </servlet-mapping> ? <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping> ? <session-config> <!--session的过期时间为30分钟--> <session-timeout>30</session-timeout> </session-config> ? <!-- 这里省略了大概4000多行的MIME类型的定义,这里只给出两种MIME类型的定义 --> <mime-mapping> <extension>bmp</extension> <mime-type>image/bmp</mime-type> </mime-mapping> <mime-mapping> <extension>htm</extension> <mime-type>text/html</mime-type> </mime-mapping> ? <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
7. ServletContext
-
概述
-
一个项目只有一个ServletContext对象,我们可以在很多个Servlet中来获取这个唯一的对象,使用它可以给Servlet传递数据,完成共享数据。
-
ServletContext对象在Tomcat启动时创建,在Tomcat关闭时销毁
-
-
获取ServletContext
在Servlet接口中,init(ServletConfig config)方法可以获取ServletConfig对象,该对象有getServletContext()方法可以获取ServletContext对象
public class MyServlet implements Servlet { public void init(ServletConfig config) { ServletContext context = config.getServletContext(); } … }
在GenericServlet类中,有成员变量ServletConfig,有getServletContext()方法可以获取ServletContext对象
public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { ServletContext context = this.getServletContext(); } }
-
域对象的功能
-
域对象是用来在多个Servlet中传递数据,所以域对象必须要有存和取数据的功能。JavaWeb中包含四个域对象,分别是ServletContext、PageContext、HttpSession、ServletRequest
-
ServletContext对象用来操作数据的方法
-
void setAttribute(String name, Object value):用来存储一个对象,相当于在ServletContext中有一个Map对象,所以在存储时name值不能相同
-
Object getAttribute(String name):用来获取数据,因为返回值为Object对象,需要强制转换
-
void removeAttribute(String name):删除一个对象
-
Enumeration getAttributeNames():获取所有域属性的名称
-
-
-
获取初始化参数
-
Servlet也可以获取初始化参数,但它只能获取局部的初始化参数,即只能获取自己的初始化参数
-
使用ServletContext可以配置公共的初始化参数
-
<web-app...> ... <context-param> <param-name>paramName1</param-name> <param-value>paramValue1</param-value> </context-param> <context-param> <param-name>paramName2</param-name> <param-value>paramValue2</param-value> </context-param> </web-app>
ServletContext context = this.getServletContext(); String value1 = context.getInitParameter("paramName1"); String value2 = context.getInitParameter("paramName2"); System.out.println(value1 + ", " + value2);
-
获取相关资源的方法
-
获取真实路径
-
获取a.txt的真实路径String realPath = this.getServletContext.getRealPath("/a.txt");
-
windows系统下这种方法获取的路径是代盘符的
-
-
获取资源流
-
获取a.txt的t资源流:InputStream in = this.getServletContext.getResourceAsStream("/a.txt");
-
-
-
获取/WEB-INF下所有资源的路径:Set set = this.getServletContext.getResourcePaths("/WEB-INF");
-
-
以上是关于JavaWeb之Servlet一的主要内容,如果未能解决你的问题,请参考以下文章