6.Servlet
引入:
- Servlet是一个小的Java程序,该程序运行在Web 服务器中(Servlet必须要在Web服务器中运行),用于处理来自于 web 客户端(比如浏览器)的请求和响应。
- Servlet有能力在每次不同时间阶段或者后台业务数据状态发生了改变,可以来处理这种动态的数据。
- Servlet它是一个纯Java代码实现的。
- Servlet是sun公司定义的一套请求web客户端请求和响应的规范。没有实现,具体的技术规范交给了web 服务器的厂商在实现
6.1Servlet开发流程
- 编写一个自定义的类让它去实现sun公司定义的Servlet接口
/**
* 1.自定义一个java 类。
2.实现一个Servlet接口
3.导入servlet-api.jar 包 (注意加入到类路径中)
*
*/
public class HelloServlet implements Servlet {
// 该方法就是来处理请求和响应的方法
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("请求来了....");
}
- 在开发的web应用中的web.xml文件中去注册自定义的Servlet以及映射该Servlet的uri地址
<!-- 注册自定义的Servlet:向tomcat服务器注册了一个Servlet
servlet 标签 : 用于注册自定义的Servlet
servlet-name 该子标签:用于给自定义的Servlet 取个别名
servlet-class 该子标签:用于注册具体的Servlet 的权限类路径 (绑定要注册的servlet)
-->
<servlet>
<servlet-name>hs</servlet-name>
<servlet-class>com.xingxue.servlet.hello.HelloServlet</servlet-class>
</servlet>
<!-- 映射servlet 的uri 地址
servlet-mapping 标签: 用于映射一个具体的servlet 供web浏览器外部访问的 uri地址.
servlet-name 该标签:指定需要映射servlet的别名
url-pattern 该标签:指定web客户端浏览器访问的uri地址
-->
<servlet-mapping>
<servlet-name>hs</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
6.2Servlet创建三种方式
- 第一种方式:自定义一个类实现Servlet接口
- 第二种方式:自定义一个类继承GenericServlet抽象类(因为该类实现了Servlet接口)
- 第三种方式:自定义一个类继承HttpServlet类
6.3Sevlet生命周期方法
- Servlet对象实例默认情况下是由第一次请求来的时候才会被创建
- Servlet对象实例创建的只有一次
- Servlet对象实例是由tomcat Servlet容器完成创建
- 生命周期方法:(面试题)
- public void service(ServletRequest req, ServletResponse res):该方法是处理请求和响应的
- public void init(ServletConfig config):该方法是在servlet对象实例创建后就会执行的方法,该方法是由tomcat 相关的组件在调用,并且调用一次。
- public void destroy():该方法会在应用从tomcat中卸载,tomcat服务器关闭的时候自动执行。
6.4 ServletConfig 对象详解
- 该对象是一个对Servlet描述信息的封装对象。
- 该对象不需要程序员手工创建,是由tomcat容器在servlet对象初始化的时候就会被创建。
- 该对象类型api方法介绍
- getServletName() 该方法获取的是servlet-name标签中的值
- getInitParameter(String key) 该方法可以获取指定的当前servlet 配置的初始化参数。
- getInitParameterNames()该方法获取当前servlet配置的所有的key
- getServletContext()该方法可以获取应用域对象ServletContext
注意获取servlet上下文初始化参数需要在web.xml文件中配置
<servlet>
<servlet-name>sd1</servlet-name>
<servlet-class>com.xingxue.servlet.demo.ServletDemo1</servlet-class>
<!-- 当前servlet的初始化参数:数据结构是key:value形式
param-name 标签为 key
param-value 标签 value
-->
<init-param>
<param-name>username</param-name>
<param-value>lisi</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
</servlet>
6.5ServletContext 对象详解
- ServletContext是描述一个web 应用的上下文对象
- ServletContext针对web 应用有且只要一个该对象
- ServletContext对象是通过ServletConfig对象获取
- ServletContext对象也是Servlet中的三大域对象之一(日后再说)
- ServletContext对象既然是一个web 应用的上下文对象,所以可以通过该对象来获取web 应用上下文中的资源文件
- ServletContext对象 api方法介绍
- getInitParameter(String key):获取应用上下文初始化参数值
- getRealPath(String 相对应用的路径path):获取资源化在磁盘上路径
- getResourceAsStream(String 相对应用的路径path):获取资源并把资源转换成字节输入流
- setAttribute(name, object);该方法可以把数据放入到一个map中。该map作用域是一个应用域
- getAttribute(name); 该方法可以从map中获取值,该map作用域是一个应用域
6.6Servlet细节
- Servlet是一个线程不安全的对象(面试题)
如果开发一个HelloServlet这样一个Servlet组件,发现Servlet只会在第一次请求来的时候创建一次,以后的请求不再创建该Servlet组件对象。所以可以了解到多个请求同一个servlet是共享的对象。然而,不同的请求可以理解成多个线程在操作同一分对象数据,所以就有可能出现线程并发的问题。
注意:所有将来的数据,不能暴露在servlet的成员变量位置,需要的话写在处理请求和响应的service方法中。
- Servlet 创建时机
默认情况下Serlvet创建的时机是在第一次请求来的时候才会创建,所有如果有大量的servlet初始化化工作比较耗时的话,第一次访问者体验不好。要解决该问题,就要把创建servlet的时机提前,可以提前到应用发布的时候
<servlet>
<servlet-name>sd2</servlet-name>
<servlet-class>com.xingxue.servlet.demo.ServletDemo2</servlet-class>
<!-- 如果加上该标签,就可以把当前的servlet创建时机提前到应用发布的时候,该标签中的值必须是整形,该值越小,越早被创建
-->
<load-on-startup>1</load-on-startup>
</servlet>
- 映射路径问题
- 精确配置:/servlet1
- 通配符匹配:/* 匹配所有
- 后缀名匹配 : *.do
总结:精确配置的uri路径的优先级最高,精确配置可以和后缀名一起用/abc.java,
通配符不能喝后缀名一起用 /*.do 是错误的!!!
6.7Servlet请求流程
6.8HttpServlet对象详解 (掌握 、重点)
- HttpServletRequest 对象详解
该对象继承了ServletRequest对象,能处理HTTP请求的Servlet
该对象是Servlet 容器创建的(tomcat服务器),帮助注入到生命周期方法中的service的形参上
该对象的api:
- getParameter(String key)通过key获取请求参数
- getMethod()该方法获取请求的请求方式
- getRequestURI():获取请求的uri地址
- getRequestURL():获取请求的url地址
- getParameterNames():获取请求参数的key的集合
- getParameterValues(String key):获取指定的请求参数的key获得一组值
- HttpServletResponse 对象详解
该对象继承了ServletResponse对象,能处理HTTP请求的Servlet
该对象是Servlet 容器创建的(tomcat服务器),帮助注入到生命周期方法中的service的形参上
该对象的api:
- getOutputStream():使用的字节流向web客户端进行响应 (响应任何的数据类型)
- getWriter();使用的字符流向web客户进行响应 (响应文本数据类型)
- 以上的两个流对象不能同时使用,同时使用报错!!!
- setCharacterEncoding("utf-8") : 响应数据指定码表来编码
- setContentType("text/html;charset=utf-8") : 告诉浏览器使用指定的码表打开,该方法其实也具有setCharacterEncoding这个方法的特性,所有指定该方法就可以了。
- 中文乱码问题
请求方式POST中文乱码处理:
- HttpServletRequest对象中的setCharacterEncoding(String 码表),设置的码表要看提交参数的页面使用的什么的码表。
请求方式GET中文乱码处理:
- 修改tomcat服务器的码表,在tomcat7版本以下的服务器默认的码表是iso8859-1,tomcat7以上使用的utf-8.URIEncondig
- 还有使用手工转码,详见代码
- 转发和重定向