Servlet
1.什么是Servlet?
①是JavaEE规范之一。规范就是接口
②是运行在服务器端的一个java程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
③是Javaweb三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。
2.手动实现Servlet
①创建javaee项目,定义一个类,实现Servlet接口(5个方法)
②实现接口中的抽象方法
③配置Servlet
web.xml的配置如下:
<!--servlet标签给Tomcat配置Servlet程序-->
<servlet>
<!--servlet-name标签 Servlet程序起一个别名(一般是类名)-->
<servlet-name>ServletTest01</servlet-name>
<!--servlet-class是Servlet程序的全类名(也就是ServletTest01对应的那个类)-->
<servlet-class>com.wr.test.ServletTest01</servlet-class>
</servlet>
<!--servlet-mapping标签给Servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
<servlet-name>ServletTest01</servlet-name>
<!--url-pattern标签配置访问地址
/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
/hello 表示地址为:http://ip:port/工程路径/hello (hello自定义)
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
注意:<url-pattern>/xxxx</url-pattrn> 斜杠一定要加,否则会报一个错误:during artifact deployment. See server log for details.,(检查了Tomcat部署完成并且在Project Structure中Artifacts配置也无误)。论斜杠的重要性,初学者容易忘记加它。
3.执行原理
1)当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
2)查找web.xml文件,是否有对应的<url-pattern>标签内容。
3)如果有,则在找到对应的<servlet-class>全类名
4)Tomcat会将字节码文件加载进内存,并且创建其对象
5)调用其方法
4.Servlet中的生命周期
1.init():初始化方法,在Servlet被创建时 执行,只执行一次(说明一个Servlet在内存中只存在一个对象,Servlet是单例的),多个用户访问时可能存在线程安全问题。解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量也不要修改其值。它传递一个实现了javax.servlet.ServletConfig接口的对象,使得servlet能够从web application中获取初始化参数 。
*Servlet什么时候被创建?默认情况下,第一次被访问时,Servlet被创建
可以配置执行Servlet的创建时机:(在<Servlet>标签下配置)
1.第一次被访问时,创建 <load-on-startuo>的值为负数
2.在服务器启动时,创建 <load-on-startuo>的值为0或正整数
2.service():提供服务方法,Servlet被访问一次,该方法就执行一次,多次执行。每个请求的处理都在独立的线程中进行。web服务器对每个请求都会调用一次这个方法。service()方法判断请求的类型,并把它转发给相应的方法进行处理。
3.destory():销毁方法,Servlet被销毁(关闭Tomcat)时 执行,只执行一次
只有服务器正常关闭时,该方法才会执行。且方法在Servlet被销毁之前执行,一般用于释放资源。
和所有的java程序一样,Servlet运行在JVM中。引入Servlet容器是为了处理复杂的HTTP请求,Servlet容器负责Servlet的创建、执行和销毁。
5.注解(Servlet3.0以上版本可使用WebServlet注解,免去创建web.xml)
@webServlet("资源路径") 即配置urlPatterns = "/XXXX" XXXX:自定义
6.Servlet的体系结构
Servlet--接口,由于写一个类实现Servlet接口得重写它里面的五个方法,但又不常用,可用其他方式实现Servlet接口:
① GenericServlet --抽象类(Servlet接口子类)(将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象)。如此一来,在定义Servlet类时,可以继承GenericServlet,实现service()方法即可;当然,想实现哪个方法就可以重写哪个,相对于implements Servlet来说,只是不需要重写五个方法而已。② HttpServlet--抽象类(Servlet接口‘孙子类’):对http协议的一种封装,简化操作,它继承了GenericServlet 。
1.定义类继承HttpServlet
2.重写doGet、doPost方法
备注:HttpServlet继承了GenericServlet类,它的实现原理是:在实现Servlet的方法时,需要写一个方法判断请求方式(get还是post),后来写了两个方法分别是doGet()和doPost()方法,提供给上面的判断请求方法来调用。
//传统方式
public class ServletDome1 implements Servlet {
//要重写五种方法
}
/*
* 2.定义一个类继承GenericServlet,而不是直接实现Servlet接口,只
* 用重写service方法即可,想要实现其他的方法就再去重写。
* */
@WebServlet(urlPatterns = "/demo2")
public class ServletDome2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("继承GenericServlet抽象类。。。");
}
@Override
public void init() throws ServletException {
super.init();
}
}
/*
* 3.定义类继承HttpServlet抽象类,
* 底层HttpServlet是继承了GenericServlet
* 不要求重写Servlet接口里的5个方法,但是原则上我们需要重写doGet和doPost方法。
* */
@WebServlet("/demo3")
public class ServletDome3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet。。。");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost。。。");
}
}
7.Servlet相关配置
1.urlpartten:Servlet访问路径
1.一个Servlet可以定义多个访问路径:@WebServlet({"/d4","/dd4","/dd4"})
2./xxx/xxx:多层路径
3.*.do:扩展名匹配
//@WebServlet({"/d4","/dd4","/dd4"})//这三个路径都能访问
//@WebServlet("/user/demo4")//两层路径
//@WebServlet("/user/*")//*表示通配符,那个符号都可以
//@WebServlet("/*")
//@WebServlet("*.do")//该方法不能加斜杠,*好后面.什么都可以
8.ServletContext类
1.servletContext是一个接口,他表示servlet上下文对象
2.一个web工程,只有一个ServletContext对象实例
3.ServletContext对象是一个域对象
什么是域对象?
就是可以像Map一样存取数据的对象,叫域对象。这里的域对象指的是存取数据的操作范围。
存数据 | 取数据 | 删除数据 | |
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
ServletContext类的四个作用
1.获取web.xml中配置的上下文参数 context-param
2.获取当前的工程路径,格式:/工程路径
3.获取工程部署后的在服务器硬盘上的绝对路径
4.像Map一样存取数据
9.转发和重定向
重定向:资源跳转的方式
特点:
1.地址栏发生变化
2.重定向可以访问其他站点(服务器)的资源
3.重定向是两次http请求和响应
转发特点:
1.地址栏不发生变化
2.只发生在服务器内部,只能访问当前服务器下的资源
3.转发是一次http请求和响应
HTTP
概念:Hyper Text Transfer Protocol 超文本传输协议
*传输协议:定义了 客户端和服务器端通信时,发送数据的格式
*特点:
1.基于TCP/IP的高级协议
2.默认端口号:80
3.基于请求/响应模型的:一次请求对应一次响应
4.无状态的:每次请求之间相互独立,不能交互数据
请求消息数据格式
1.请求行
请求方式 请求url 请求协议/版本 :GET /login.html HTTP/1.1
#请求方式:HTTP协议有7种请求方式,常用的有2种get、post
get:请求参数在请求行中,在url后。请求的url长度是有限制的。请求不太安全
post:求参数在请求体中;请求的url长度没有限制;请求相对安全
2.请求头
请求头名称:请求值,请求值(多个请求值用逗号隔开) 客户端浏览器告诉服务器一些信息。
常见的请求头:
1.User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
可以在服务器端获取该头的信息,解决浏览器的兼容性问题
2.Accept:可以解析的文件(HTML、css、。。。。)类型
3.Accept-Language:可以解析的语言类型
4.Referer:http://localhost/login.html 告诉服务器,我从哪里来?
3.请求空行
空行
4.请求体(正文)
封装POST请求消息的请求参数的
get请求没有请求体,post才有
响应消息数据格式
1.Tomcat服务器会根据请求url中的资源路径,创建对应的ServletDome类的对象。
2.Tomcat服务器会创建request和response对象,request对象中封装消息数据。
3.Tomcat将request和response两个对象传递给service方法,并且调用service方法。
4.我们可以通过request对象获取请求消息数据,通过response对象设置响应消息数据。
5.服务器在给浏览器做出响应之前,会从response对象中拿程序员设置的响应消息数据。
Request
1.request对象和response对象的原理:
1.request和response对象是由服务器创建的。我们来使用它
2.request对象是来获取请求消息,response对象是来设置响应消息
2.request对象体系结构
ServletRequest --接口 --继承--> HttpServletRequest --接口 --实现--> org.apache.catalina.connector.ResquestFacade类(tomcat)
3.request功能
1.获取请求消息数据
①获取请求行数据
*GET /day01/demo1?name=laowang HTTP/1.1
*方法:
*设置请求编码:req.setCharacterEncoding("UtF-8");
1.获取请求方式:GET String getMethod()
2.获取虚拟目录:/XXXX String getContextPath()
3.获取Servlet路径:/requestdemo1String getServletPath()
4.获取get方式请求参数:(参数名+值) String getQueryString()
5.获取请求url:/XXXX/requestdemo1
返回请求行中的参数部分:
String getRequestURI()::/XXXX/demo1
返回客户端发出请求时的完整URL:
StringBuffer getRequestURL(): http://localhost/XXXX/requestdemo1
6.获取协议及版本:HTTP/1.1 String getProtocal()
7.获取客户机的IP地址:String getRemoteAddr()
8.获取客户机的完整主机名:getRemoteHost()
9.获取URL中的额外路径信息:getPathInfo()
10.获取客户机使用的网络端口号:getRemotePort()
11.获取WEB服务器的IP地址:getLocalAddr()
12.获取WEB服务器的主机名:getLocalName()
2.获取请求头数据
String getHeader(String name):通过请求头的名称获取请求头的值
Enumeration<String> getHeaderNames():获取所有的请求头名称(当成迭代器来使用)
3.获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了post请求的请求参数
步骤:
1.获取流对象
*BufferedReader getReader():获取字符输入流,只能操作字符数据
*ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
会话技术:
1.会话:一次会话中包含多次请求和响应
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止。
2.功能:在一次会话的范围内的多次请求间,共享数据。
3.java常用会话方式:
1.cookie(客户端会话技术)将数据保存到客户端
步骤:1.创建cookie对象,绑定数据
*new Cookie(String name,String value)
2.发送cookie对象
*resp.addCookie(Cookie cookie)
3.获取cookie,拿到数据 (可用循环取出数据)
*Cookie[] c = request.getCookie()
4.实现原理:基于响应头set-cookie和请求头cookie实现
细节:
1.可用创建多个Cookie对象,response多次调用addCookie,来实现一次发送多个cookie。
2.持久化存储:setMaxAge(int seconds)可传正数(将cookie数据写到硬盘的文件中,持久化存储,表示cookie存活时间,时间到了cookie数据会自动删除)、负数(默认值,即浏览器或服务器一关就数据就删除了)、零(删除cookie信息)
2.session(服务器端会话技术)
tomcat中处理session的具体方式:
1.浏览器第一次访问服务器的时候,服务器就会开辟本次会话的session,这个session空间有一个id叫JSESSIONID(tomcat中叫这个)
* 2.当服务器结束处理以后,会将response对象转发给servlet容器进行处理,在servlet容器中,会设置一个cookie键值对,键为JSEESIONID,值为本次会话的session这个id
* 3.浏览器接收到响应以后,发现响应报文中有cookie键值对,于是就将这个cookie键值对保存在浏览器的cookie文件中
* 4.浏览器第二次访问服务器的时候,就会将这个cookie键值对添加到请求头(说白了就是将JSESSIONID带上)
* 5.服务器接收到浏览器的第二次请求的时候,servlet容器就获取到了这个 JSESSIONID:XXXXX,于是就去服务器空间中找到了这个对应的session,添加到本次的request对象中
* 6.在servlet中,就直接通过request.getSession获取到这个session对象
3.sssion好cookie的生命周期
cookie:默认情况下浏览器关闭后,cookie就销毁。
session:在服务器内session的默认过期时间是30分钟(即30分钟后session空间就自动销毁了,但session对象依然存在)。