Servlet重点

Servlet 生命周期

启动tomcat服务器,服务器会扫描webapps下所有项目的web.xml文件,将web.xml中servlet的url-partten与全类名组成键值对存储与map1集合中;

Map<String, String>

key             value
---------------------------------------------------------
/login          cn.qkmango.javaweb.servlet.LoginServlet
/delete         cn.qkmango.javaweb.servlet.DeleteServlet
/insert         cn.qkmango.javaweb.servlet.InsertServlet

当第一次访问某个servlet时,会通过map1得到该servlet的全类名,通过反射调用该servlet的无参构造方法,创建一个servlet对象(单例),然后将该servlet的url-partten与实例形成键值对存入另外一个map集合;

Map<String, Servlet>

key             value
--------------------------------------
/login          LoginServlet对象的引用
/delete         DeleteServlet对象的引用
/insert         InsertServlet对象的引用

描述Servlet对象生命周期

1)浏览器访问URL:http://localhost:8080/web_war_exploded/hello
2)web容器截取请求路径:/web_war_exploded/hello
3)web容器在容器上下文中找请求路径/web_war_exploded/hello对应的Servlet对象
4.1)若没有找到对应的Servlet对象

  • 会通过web.xml文件中的相关信息(实际上通过map),得到请求路径/web_war_exploded/hello对应的Servlet完整类名
  • 通过反射机制,调用Servlet类的无参构造方法完成Servlet对象的实例化
  • web容器调用Servlet对象的init()方法完成初始化
  • web容器调用Servlet对象的service()方法提供服务

4.2)若找到对应的Servlet对象

  • web容器直接调用Servlet对象的service()方法提供服务

5)Servlet对象销毁

  • web容器关闭的时候、webApp重新部署的时候、该Servlet对象长时间没有用户访问的时候,web容器会将Servlet对象销毁,在销毁Servlet对象前,会调用对象的destroy()方法进行销毁前的准备

ServletConfig接口

ServletConfig是一个Servlet对象的配置信息对象,ServletConfig对象中封装了一个Servlet对象的配置信息。Servlet对象的配置信息在web.xml文件中,一个Servlet对象对应一个ServletConfig对象对象,100个Servlet对象对应100个ServletConfig对象。

ServletConfig接口中的方法

  • String getInitParameter(String name) 通过name,获取初始化参数name对应的value

    //获取name为driver所对应的value
    String driver = servletConfig.getInitParameter("driver");
    
  • Enumeration getInitParameterNames() 获取初始化参数的name集合。

    //获取name集合
    Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
    //通过name集合循环遍历拿出name,通过name获取value
    while (initParameterNames.hasMoreElements()) {
        String name = initParameterNames.nextElement();
        String value = servletConfig.getInitParameter(name);
        writer.print(name + " = " + value + "<br>");
    }
    
  • String getServletName() 获取servletName,<servlet-name>servletName</servlet-name>

    String servletName = servletConfig.getServletName();
    
  • ServletContext getServletContext() 获取ServletContext【Servlet上下文】对象

    ServletContext servletContext = servletConfig.getServletContext();
    

ServletContext接口

ServletContext到底是什么?什么时候被创建?什么时候被销毁?创建几个?

  • ServletContext被译为:Servlet上下文
  • 一个webapp只有一个web.xml文件,web.xml文件服务器启动阶段被解析
  • 一个webapp只有一个ServletContext对象,ServletContext对象在服务器启动阶段被实例化
  • ServletContext在服务器关闭的时候被销毁
  • ServletContext对应的是web.xml文件,是web.xml文件的代表
  • ServletContext是所有Servlet对象四周环境的代表,被所有Servlet共享【在同一个webapp中,所有Servlet对象共享一个四周环境对象,该对象就是ServletContext
    • 所有用户若想共享同一个数据,可以将数据放到ServletContext对象中(写到web.xml文件中,或后期通过方法添加)
    • 一般放到ServletContext对象中的数据不建议涉及到修改操作的,以为ServletContext是多线程共享的一个对象,修改的时候会存在线程安全问题

ServletContext接口中有哪些常用方法

 - void `setAttribute(String name, Object object)` 向ServletContext中添加数据
 - Object `getAttribute(String name)` 从ServletContext中获取数据
 - void `removeAttribute(String name)` 从ServletContext中移除数据
 - String `getInitParameter(String name)` 从ServletContext中获取name所对应的value初始化参数(\<context-param>标签中)
 - Enumeration `getInitParameterNames()`从ServletContext中获取name所对应的value初始化参数(\<context-param>标签中)
 - String `getRealPath(String path)` 获取文件绝对路径

ServletConfig与ServletContext中的getInitParameter()getInitParameterNames()不同

  1. ServletConfig是每个Servlet对象的配置信息对象,ServletConfig中的getInitParameter()getInitParameterNames()获取到的初始化参数是在<init-param>标签中的,<init-param>标签定义在<servlet>标签里面

  2. ServletContext是所有Servlet对象的共用的四周环境,ServletContext中的getInitParameter()getInitParameterNames()获取到的参数是在<context-param>标签中的,<context-param>标签定义在<web-app>标签里面

ServletContext中的getInitParameter(String name)getAttribute(String name)不同

  1. getInitParameter(String name)获取到的参数是写在web.xml文件<context-param>标签中的,获取到的都是字符串参数
  2. getAttribute(String name)获取到的数据是运行时添加到ServletContext中的数据,数据可以是任何类型,不同用户都可以通过name获取到数据

欢迎页面

  1. 欢迎页面是怎么设置的?
    假设在web/html目录下创建welcome.html,想让welcome.html作为整个webapp的欢迎页面,应该在web.xml文件中添加如下标签

    <!--将welcome.html页面作为欢迎页面-->
    <!--注意开头没有“/”-->
    <welcome-file-list>
        <welcome-file>html/welcome.html</welcome-file>
    </welcome-file-list>
    
  2. 为什么设置欢迎页面?

    • 为了访问更方便,为例提高用户的体验
    • 设置欢迎页面之后,直接在浏览器地址栏上访问该webapp即可,自动定位到欢迎页面,例如http://localhost:8080/webapp07/
  3. 欢迎页面可以设置多个
    设置多个欢迎页面,越靠上越优先,当前面的欢迎页面找不到时才使用后面的欢迎页面

    <welcome-file-list>
        <welcome-file>html/welcome.html</welcome-file>
        <welcome-file>html/welcome2.html</welcome-file>
    </welcome-file-list>
    
  4. 欢迎页面可以是任何一种web资源
    欢迎页面不仅可以是html文件,也可以时任何一种web资源,如Servlet
    使用Servlet作为欢迎页面

    1. 在web.xml文件中配置好Servlet
    2. <welcome-file>标签内填写<servlet>标签中的<url-pattern>标签中的内容,要注意,此时要去掉开头的“/”
    <!--配置Servlet-->
    <servlet>
        <servlet-name>welcome</servlet-name>
        <servlet-class>cn.qkmango.Welcome</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>welcome</servlet-name>
        <url-pattern>/system/welcome</url-pattern>
    </servlet-mapping>
    
    <!--Servlet作为欢迎页面-->    
    <welcome-file-list>
        <!--注意此处,去掉开头的“/”-->
        <welcome-file>system/welcome</welcome-file>
    </welcome-file-list>
    

常见的错误代码 自定义错误页面(webapp08)

  • 404 Not Found 资源未找到
  • 500 Server Inner Error 服务器内部错误,一般都是服务器Java程序出现异常

404和500是HTTP协议状态码,是W3C制定的
正常响应的HTTP协议状态码是200

可以在web.xml中添加错误页面,当发生该错误时,自动跳转到指定页面

<error-page>
    <error-code>404</error-code>
    <!--此处的路径前省略了项目的根目录web目录,即相对于当前项目的根目录-->
    <location>/errorPage/404.html</location>
</error-page>

Servlet路径的总结

客户端浏览器要处理的URL路径时,此时/前代表的是主机名,如http://localhost:8080,所以我们要以/webappName开头。
例如页面有一个链接

<a href="/oa/login">登陆</a>

当你在浏览器点击这个超链接时,浏览器就会请求http://localhost:8080/oa/login,所以,在需要浏览器请求的URL时,/前省略了主机名。
后台服务器处理请求URL路径时,以/开头,例如在web.xml文件中配置的servlet,此处的<url-pattern>/login</url-pattern>就是以/开头,/前省略了hostName和webappName

<servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>cn.qkmango.login</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

注意:
在欢迎页面中的路径,是不以’’/’'开头的。
在重定向中的路径,要"以/项目别名"开头,跟在浏览器客户端相似。

自定义servle的三种方式

  1. 实现Servle接口
  2. 继承GenericServlet类
  3. 继承HttpServlet类

get与post方式发送请求

GET请求:如下是一个GET请求的登陆页面的请求,由于请求方式为GET,所以发送数据在请求行上发送!故请求体为空

GET /webapp10/login?username=admin&password=123 HTTP/1.1 请求行
Accept: text/html, application/xhtml+xml, image/jxr, */* 消息报头
X-HttpWatch-RID: 50301-10022
Referer: http://localhost:8080/webapp10/
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
														 空白行
														 请求体

POST请求:如下是一个POST请求的登陆页面的请求,请求体展示了请求的内容username=admin&password=***

POST /webapp10/login HTTP/1.1 请求行						
Accept: text/html, application/xhtml+xml, image/jxr, */* 消息报头
X-HttpWatch-RID: 50301-10054
Referer: http://localhost:8080/webapp10/
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 27
Connection: Keep-Alive
Cache-Control: no-cache
						空白行
username=admin&password=123 请求体
响应协议

响应协议包括四部分

  • 状态行
  • 响应报头
  • 空白行
  • 响应体

状态行:协议版本号 状态码

空白行:是用来分离响应报头和响应体的

响应协议中重点掌握状态码:

  • 200 响应成功正常结束

  • 404 资源未找到

  • 500 服务器内部错误

如下是服务器的响应

HTTP/1.1 200 OK 状态行
Server: Apache-Coyote/1.1 响应报头
Content-Type: text/html;charset=UTF-8
Content-Length: 21
Date: Thu, 13 Aug 2020 10:15:13 GMT
	空白行
<h1>登陆成功</h1> 响应体
GET请求与POST请求区别
  • 什么情况下浏览器发送的请求是GET请求,什么情况下浏览器发送的请求是POST请求?

    只有当使用表单form,并且讲form的标签的method属性设置为method=“post”,才是POST请求方式,其余剩下的所有请求都是基于GET请求

  • GET请求和POST请求有什么区别?

    • GET请求在请求行上提交数据,格式uri?name=value&name=value,这种提交方式最终提交的数据会显示在浏览器地址栏上
    • POST请求在请求体中提交数据,相对安全,提交格式name=value&name=value,这种提交方式最终不会显示在浏览器地址栏上
    • POST请求在请求体中提交数据,所以POST请求提交的数据没有长度限制【POST可以提价大数据】
      - GET请求在请求行上提交数据,所以GET请求提交的数据长度有限制
    • GET请求只能提交字符串数据,POST请求可以提交任何类型的数据,包括视频…,所以文件上传必须使用POST请求
    • GET请求最终的结果,会被浏览器缓存收纳,而POST不会被缓存收纳(为什么GET会被缓存?)
  • GET请求和POST请求应该如何选择?

    • 有敏感数据 POST
    • 传送的数据不是普通字符串 POST
    • 传送的数据非常多 POST
    • 这个请求是为了修改服务器端资源 POST
    • GET请求多数情况下是从服务器中读取资源,这个读取的资源在短时间内不会发送变化,所以GET请求最终的结果会被浏览器缓存起来
    • POST请求是为了修改服务器端的资源,而每一次修改结果都是不同的,最终结果没有必要被浏览器缓存

缓存解决方案

浏览器将资源缓存后,缓存的资源是和某个特定的路径绑定在一起的,只要浏览器再发送这个相同的请求路径,这个时候浏览器就会去缓存中获取资源,不再访问服务器,以这种方式降低服务器的压力,提高用户体验。

但是有的时候我们并不希望走缓存,希望每一次后哦访问服务器,可以在请求路径后面添加时间戳,例如:http://ip:port/oa/system/logout?timetamp=1234564635423

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值