目录
概念
servlet = server + applet,即运行在服务器端的小程序,是Java web的核心。
- Servlet其实就是一个接口,定义了Java类被浏览器访问(Tomcat识别)到的规则。
- 我们需要定义一个类,实现Servlet接口,复写其方法,才能被Tomcat识别。
浏览器寻找动态资源时其实是访问一个特殊的Java类,它必须遵守一定的规则(接口,即Servlet),和常规的Java类不同的是它没有main方法,必须依赖于服务器才能运行,由Tomcat执行它。
快速入门 :
- 创建Java EE的项目
- 定义一个类,实现Servlet接口
- 实现Servlet接口方法
- 配置Servlet
关于配置Servlet有两种方法:
1、在web.xml文件里配置
<servlet>
<servlet-name>随便起个名字</servlet-name>
<servlet-class>你的Servlet的全类名</servlet-class>
</servlet><servlet-mapping>
<servlet-name>刚才随便起的那个名字</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>如:
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>xiaobin.servlet.ServeletDemo</servlet-class>
</servlet><servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
由此该类便可被Tomcat识别
2、注解配置(Servlet3.0以上版本):不需要web.xml //推荐!
使用@WebServlet(资源路径),比如方法一可以改为@WebServlet(“/demo1”),配置多个路径@WebServlet({“/demo1”,“demo”})
- 在浏览器键入http://localhost:8080/ServletDemo/ServletDemo/demo即可访问你写的Servlet
- 这里的路径可以是@WebServlet(“/demo1”)这种目录式的,也可以是@WebServlet(“demo1.do”)这种,注意*.do这种前面无斜杠,do只是一个后缀,随便取名。
Servlet执行原理
- 当服务器接收到客户端浏览器的请求后,会解析请求中的URL路径,获取访问的Servlet资源路径
- 查找web.xml文件看是否有对应的<url-pattern>标签体内容与资源路径一致
- 如果有,则找到对应的<Servlet-class>全类名
- Tomacat会将字节码文件加载进内存,创建其对象
- 调用其相应方法
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>xiaobin.servlet.ServeletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
Servlet的生命周期
1、初始化:init()
- Servlet被创建时执行,只会执行一次,说明Servlet在内存中只存在一个对象,是单例的,多个用户访问时可能存在线程安全问题,所以尽量不要在Servlet中定义成员变量;
- 默认第一次访问时被创建,通过<servlet>标签下的<load-on-startup>标签配置创建时间,其值为负数则是第一次访问创建,0和正数则为服务器启动时创建:<load-on-startup>1</load-on-startup>
2、提供服务:service()
每一次Servlet被访问时执行(创建时也是被访问),可被执行多次;
3、销毁(之前):destroy()
服务器正常关闭时执行,执行一次;
//ServletConfig()获取配置对象,getServletInfo()获取Servlet的一些信息。
Servlet体系结构
背景:在使用Servlet接口时往往只使用了service()等极少数方法,其余没有使用,很浪费啊。
集成结构:Servlet(接口)——>GenericServlet(抽象类)——>HttpServlet(抽象类)
- GenericServlet将Servlet的其余四个方法做了空实现,只需复写service(),其余四个要复写可以手动添加,一般不使用这个。
- HttpServlet(推荐!):对http协议的一种封装。
HttpServlet使用步骤:
- 定义类继承HttpServlet
- 重写其doPost()或者doGet()
request对象
1. request对象和response对象的原理
1. request和response对象是由服务器创建的。我们来使用它们
2. request对象是来获取请求消息,response对象是来设置响应消息
2. request对象继承体系结构
ServletRequest -- 接口
| 继承
HttpServletRequest -- 接口
| 实现
org.apache.catalina.connector.RequestFacade 类(tomcat)
3. request功能
1. 获取请求消息数据
- 获取请求行、请求头、请求体数据
(1)获取请求行数据
设请求行:GET /day14/demo1?name=zhangsan HTTP/1.1
1. 获取请求方式 :GET
* String getMethod()
2. 获取虚拟目录:/day14
* String getContextPath()
3. 获取Servlet路径: /demo1
* String getServletPath()
4. 获取get方式请求参数:name=zhangsan
* String getQueryString()
5. 获取请求URI:/day14/demo1
* String getRequestURI(): /day14/demo1
* StringBuffer getRequestURL() :http://localhost/day14/demo1* URL:统一资源定位符 : http://localhost/day14/demo1 中华人民共和国
* URI:统一资源标识符 : /day14/demo1(范围更大) 共和国
6. 获取协议及版本:HTTP/1.1
* String getProtocol()7. 获取客户机的IP地址:
* String getRemoteAddr()(2)获取请求头数据
方法:
- Enumeration<String> getHeaderNames():获取所有的请求头名称
- String getHeader(String name):通过请求头的名称获取请求头的值
(3) 获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
步骤:
- 获取流对象
* BufferedReader getReader():获取字符输入流,只能操作字符数据
* ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
- 再从流对象中拿数据
2. 其他功能
(1)获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
- String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
- String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
- Enumeration<String> getParameterNames():获取所有请求的参数名称
- Map<String,String[]> getParameterMap():获取所有参数的map集合
乱码解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8"); //字符编码应该与页面一样
(2)请求转发:一种在服务器内部的资源跳转方式 //相当于Servlet之间的跳转
步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中,即填入服务器外的网址不行。
- 转发是一次请求。
(3)共享数据
* 域对象:一个有作用范围的对象,可以在范围内共享数据
* request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
* 方法:
1. void setAttribute(String name,Object obj):存储数据
2. Object getAttitude(String name):通过键获取值
3. void removeAttribute(String name):通过键移除键值对
(4)获取ServletContext
* ServletContext .getServletContext()
Response对象
Http响应数据:
获取数据格式:响应行、响应头、响应空行、响应体(传输的数据)
(1)响应行
组成:协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。状态码都是3位数字
状态码分类:
- 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码(询问客户端要不要继续发)
- 2xx:成功。代表:200
- 3xx:重定向。代表:302(重定向),304(访问缓存),不可共享域对象,这是与请求转发的区别 ///(我办不了,你去找其他资源它能办)
- 4xx:客户端错误。如:404(请求路径没有对应的资源) 405:请求方式没有对应的doXxx方法
- 5xx:服务器端错误。代表:500(服务器内部出现异常)
(2)响应头
格式:头名称: 值
常见的响应头:
1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
* 值:
* in-line:默认值,在当前页面内打开
* attachment;filename=xxx:以附件形式打开响应体。文件下载
(3)响应空行
(4) 响应体:传输的数据
功能:设置响应消息
(1)设置响应行
1. 格式:HTTP/1.1 200 ok
2. 设置状态码:setStatus(int sc)
(2)设置响应头:setHeader(String name, String value)
(3) 设置响应体:
* 使用步骤:
1. 获取输出流
* 字符输出流:PrintWriter getWriter()
* 字节输出流:ServletOutputStream getOutputStream()
2. 使用输出流,将数据输出到客户端浏览器
注:response.setContentType("text/html;charset=utf-8");------->避免乱码
ServletContext对象
概念:代表整个web应用,可以和程序的容器(服务器)来通信。
获取:
1. 通过request对象获取
request.getServletContext();
2. 通过HttpServlet获取
this.getServletContext();
//两种方式获取的其实是一个对象。
功能:
1. 获取MIME类型:
* MIME类型:在互联网通信过程中定义的一种文件数据类型
* 格式: 大类型/小类型 text/html image/jpeg
* 获取:String getMimeType(String file)
2. 域对象:共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
* ServletContext对象范围:所有用户所有请求的数据
3. 获取文件的真实(服务器)路径
方法:String getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问