首页技术文章正文

Web核心-Servlet

更新时间:2019-01-10 来源:黑马程序员 浏览量:

Servlet概念

server applet 运行在服务器上的小程序

Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则

将来我们自定义一个类,实现Servlet接口,复写方法


快速入门

创建JavaEE项目

定义一个类,实现Servlet接口

实现接口中的抽象方法

配置Servlet:在web.xml中配置


    <!--配置Servlet-->
   

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

   

<servlet>

        <servlet-name>

            demo01

        </servlet-name>

        <servlet-class>

            cn.itcast.web.servlet.ServletDemo01

        </servlet-class>

    </servlet>

     

    <servlet-mapping>

        <servlet-name>demo01</servlet-name>

        <url-pattern>/demo01</url-pattern>

    </servlet-mapping>

   

注:一般在IDEA中配置Tmocatd的Application context为/项目名称,再调用时需要用localhost:8080/项目名称/....

Servlet的执行原理

当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径

查找web.xml,是否有对应的<url-pattern>标签内容

通过servlet-pattern找到servlet-name,又通过name找到资源的class全类名.

tomcat将类加载进内存,通过反射创建对象并调用service方法


Servlet中的生命周期

init方法-创建


初始化方法,在Servlet被创建时执行,只会执行一次
- Servlet什么时候被创建?
   *默认情况下,第一次被访问时,Servlet被创建
   *可以在web.xml中配置创建时机
     <servlet>
        <load-on-startup>
         0/正值:服务器启动时创建,值越大优先级越小,一般从2开始,因为1被tomcat占用了
           负值:第一次被访问时创建
        </load-on-startup>
     </servlet>
     
- Servlet在服务器中只有一个对象,所以说Servlet是单例的
   *多个用户同时访问时,可能存在线程安全问题
   *解决方案:尽量不要在Servlet中定义成员变量,而是使用局部变量;即使定义了成员变量,也不要对其修改值

service方法-提供服务


每一次Servlet被访问一次则执行一次

destory方法-销毁


Servlet被杀死(服务器正常关闭)时执行一次
一般用于释放资源

ServletConfig方法  获取ServletConfig对象

ServletInfo方法  获取ServletInfo,如版本.作者,信息等,但一般不实现该方法


Servlet 3.0注解配置

-[ ] 好处:支持注解配置,可以不需要web.xml了-[ ] 步骤

创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml

定义一个类,实现Servlet接口

复写方法

在类上使用@WebServlet注解进行配置


@WebServlet("资源路径")
IDEA和tomcat的相关配置

[ ]IDEA会为每一个tomcat部署项目单独建立一份配置文件


启动后服务器控制台有输出Log:
Using CATALINA_BASE:   "C:\Users\Mcdull\.IntelliJIdea2017.3\system\tomcat\Tomcat_8_5_31_webServer_2"
  在Edit Configure下就可以修改配置文件和虚拟目录

工作空间项目和tomcat部署的web项目

tomcat真正访问的是"tomcat部署的web项目","tomcat部署的web项目"对应着"工作空间项目"的web目录下的所有资源


!!!!理解
采用的部署方式为第三种,在config/catalina/下部署
打开Using CATALINA_BASE路径,可以找到config/catalina/day13_servlet.xml
打开servlet.xml,<Context docBase="E:\Projects\webServer\out\artifacts\day13_servlet_war_exploded" \>
里面指明了tomcat项目的路径

WEB-INFO目录下的资源不能被浏览器直接访问

断点调试


打断点,后用debug模式启动服务器
Servlet结构体系

Servlet的实现类: GenericServlet(抽象类)-->HttpServlet(抽象类)


GenericServlet
GenericServlet将除了servic()以外的方法都空实现
将来定义Servlet时可以继承GericServlet,只需实现servic类即可.
其他类也可以重写HttpServlet

-[ ]  实际上做项目时,我们一般使用GenericServlet的子类HttpServlet,因为HttpServlet封装了Http协议

不使用HttpServlet时,service方法需要实现的功能
判断用户的请求方式(get/post...)
   String method = req.getMethod();
   if("GET".equals(method)){//get方式获取数据逻辑操作}
   else if("POST".equals(methos){//post方式获取数据逻辑操作}

HttpService 将判断请求方式封装起来,并提供doGet()和doPost()方法,分别写在两个逻辑体中

1.定义类继承HttpServlet类

2.重写doGet/doPost/...方法


   

[Java] 纯文本查看 复制代码

?

1

2

3

4

5

6

7

8

   

@Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp){

        System.out.println("doGet...");

    }

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse resp){

        System.out.println("doGet...");

    }

   


Servlet urlpattern相关配置

1.urlpattern:Servlet访问路径可以有配置多个


一个Servlet可以定义多个访问路径,在注解中使用{"路径1","路径2"...}来配置

2.urlpattern:Servlet路径的定义规则


1)./xxx   以这种方式为主
2)./xxx/xxx
3).*.后缀名
[强制!]开发中后缀名只能用*.do或*.action
HTTP概念

Hyper Text Transfer Protocol:超文本传输协议

传输协议:定义了客户端和服务器端通信时发送数据的格式

特点:


  1). 基于TCP/IP的高级协议
  2). HTTP的默认端口号为80
      当访问资源时,如果服务器端口号为80,则可以省略
  3). 基于请求/响应模型的:一次请求对应一次响应
  4). 无状态的:每次请求之间相互独立,不能交互数据

历史版本:    


1.0版本:每一次请求都需要建立一个连接

1.1版本:复用连接


请求消息数据格式

请求行

格式


  请求行格式:
  请求方式  请求url      请求协议/版本
  例: GET  /login.html   http/1.1

请求方式


HTTP协议中有7种请求方式,常用的有2种
*GET:
   1.请求参数在请求行中,在url后
   2.请求的url长度是有限制的
   3.不太安全
*POST:
   1.请求参数在请求体中
   2.请求的url长度没有限制
   3.相对安全

请求头-浏览器告诉服务器一些信息

格式


   请求头格式:
   请求头名称:请求头值

请求头名称


常见的请求头:
   1.User-Agent**:浏览器告诉服务器,访问者使用的浏览器版本信息
      *可以在服务器端获取该头信息,解决浏览器兼容性问
   2.Referer**:告诉服务器,当前请求从哪里来(发起请求的页面)
      *例:Referer:http://localhost:8080/day_14/login.html
      *作用:
        1)防盗链:
            if(referer.equals()){操作}
            else{"想看吗?来XXX网站吧!"}
        2)统计工作:
            统计工作:统计请求来源
            if(refer.eauals("百度"){百度++}
            else if(){}...
   3.Connection:告诉服务器连接的状态(是否可服用)
   4.Host:请求主机的地址
   5.Accept:告诉服务器,作为浏览器可以解析什么格式的文件

请求空行-用于分割POST请求的请求头和请求体

空行

请求体(正文)-封装post请求消息的请求参数

格式


参数名=参数值
响应消息数据格式

响应行

组成


协议/版本 响应状态码 状态码的描述

响应状态码:服务器高速客户端浏览器本次请求和响应的一个状态


分类:
  1xx: 服务器接收客户端消息,没有接收完成,等待一段时间后,发送1xx
  2xx: 成功   代表状态码:200
  3xx: 重定向 代表状态码:302(重定向) 304(访问缓存)
  4xx: 客户端错误 代表状态码:404(请求路径错误) 405(请求方式没有对应的doXXX方法)
  5xx: 服务器错误 代表状态码:500(服务器内部出现异常)

响应头

格式


头名称:值

常见的响应头


1.Content-Type:服务器告诉客户端响应体数据格式以及编码格式
  例:Content-Type:text/html;charset=UTF-8
2.Content-disposition:服务器告诉客户端以什么格式打开响应体数据
  *值:  
     *in-line:默认值,在当前页面内打开
     *attachment;filename=xxx:以附件形式打开响应体.文件下载

响应空行

响应体:传输的数据


响应字符串格式Request对象Request和Response对象的原理

1.tomcat服务器会根据请求url中的资源路径,创建对应的Servlet对象

2.tomcat服务器会创建request和response对象;request对象中封装消息数据

3.tomcat将request和response两个对象传递给service方法,并调用service方法

4.程序员可以通过request对象来获取请求消息数据;可以通过response对象来设置响应数据

5.tomcat在给浏览器作出响应之前,会从response对象中获取消息响应数据并响应给浏览器

注意:


1) request和response对象是由服务器创建的,我们来使用它们
2) request对象是来获取请求消息,response对象来设置响应消息
Requset对象的继承结构

ServletRequset(接口)->HttpServletReqest(接口)->RequestFacade(tomcat写的实现类)


Request对象的功能获取请求消息数据

1.获取请求行数据


-请求行数据:  GET /day14/demo01?name=zhangsan HTTP/1.1
-获取方法:
1)获取请求方式: GET
  *String getMethod()
2)获取虚拟目录**: /day14
  *String getContextPath()
3)获取Servlet路径  /demo1
  *String getServletPath()
4)获取请求参数  /name=zhangsan
  *String getQueryString()
5)获取请求的URI**: /day14/demo1
  *String getRquestURI :/day14/demo1
  *StringBuffer getRequestURL: http://localhost/day14/demo1
6)获取浏览器的协议及版本 HTTP/1.1
  *String getProtocol()
7)获取客户机的IP地址
  *String getRemoteAddr()
注意:
URL:统一资源定位符 http://localhost//day14/demo1
URI:统一资源标识符
day14/demo1
URL的范围比URI的范围小

2.获取请求头数据


1) String getHeader(String name):通过请求头名称获取请求头的值
2) Enumeration<String> getHeadernames():获取所有请求头的名称
   Enumberation 和 Iterator类似:
     hasMoreElement()  <-->  hasNext()用于判断
     nextElement()     <-->  next() 用于获取下一下元素

3.获取请求体数据只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数


步骤:
1).获取流对象
  *BufferedReader getReader():获取字符输入流
  *ServletInputStream getInputStream():获取字节输入流
2).从流对象中获取数据

4.总结:常用的方法

1)获取虚拟目录:getContextPath()

2)获取请求URI:getRequestURI()/getRequestURL()

3)获取请求头:getHeader(String name)


==其他功能==

==1.获取请求参数(通用方式)==


1)String getParameter(String name):根据参数名称获取参数值
2)String[] getParameterValues(String name): 根据参数名称获取参数值的数组,多用于复选框
  如:hobby=xx&hobby=game
3)Enumeration<String> getParameterNames():获取所有请求的参数名称
4)Map<String,String[]> getParameterMap():获取所有参数的map集合
- 中文乱码问题
   *get方式: tomcat8 已经将get方式乱码问题解决了
   *post方式: 会乱码
        解决:在获取参数前,设置request编码
        request.setCharacterEncoding("utf-8")

==2.请求转发:一种在服务器内部的资源跳转的方式==

步骤


1)通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
2)使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse)

特点


1) 浏览器地址栏路径不发生变化2) 只能转发至当前服务器的内部资源中3) 转发是一次请求

==3.数据共享==

域对象:一个有作用范围的对象,可以在范围内共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中去共享数据

request资源共享方法


1) void setAttribute(String name ,Object obj) :存储数据2) Object getAttribute(String name) 通过键来获取值3) void removeAttribute(String name) 通过键来移除键值对

==4.获取ServletContext对象==


-ServletContext getServletContext()
BeanUtils

用于封装JavaBean


JavaBean

JavaBean:标准的Java类

类必须被public修饰

必须提供空参的构造器

成员变量必须使用private修饰

提供公共的setter和getter方法

JavaBean的功能:封装数据


概念

成员变量

属性:setter和getter方法截取后的产物


例如:getUsername()-->Username-->username大部分情况下属性和成员变量是一样的
BeanUtils的方法

1.setProperty(javaBean,"属性名","值")

2.getProperty(javaBean,"属性名")

3.populate(javaBean,属性集map)


Response对象

功能:设置响应消息

设置响应行

设置响应头

设置响应体


设置响应行1.格式HTTP/1.1 200 ok2.设置状态码setStatus(int sc)
设置响应头

setHeader(String name, String value)

设置响应体

使用步骤


1.获取输出流  *字符输出流:PrintWriter getWriter()  *字节输出流:ServletOutputStream getOutputStream()2.使用输出流将数据输出到客户端浏览器
案例完成重定向(redirect)

代码实现


//1.设置状态码为 302response.setStatues(302);//2.设置响应头locationresponse.setHeader("location","/虚拟路径/资源路径")

简单的重定向方法


resonpse.sendRedirect("/虚拟路径/资源路径")

重定向的特点


1. 地址栏发生变化2. 重定向可以访问其他服务器的资源3. 重定向是两次请求

路径写法:


1.相对路径: 通过相对路径不可以确定唯一资源    * 以 ./开头 表示当前路径    * 以 ../开头 表示后退一级    *规则: 找到当前资源和目标资源之间的相对位置关系 2.绝对路径: 绝对路径可以确定唯一资源   在这里可以写为/虚拟路径/资源路径

在浏览器输出字符数据

代码实现


//1.获取字符输出流PrintWriter pw = resp.getWriter();//2.向浏览器写出字符数据pw.write("<h1>你好,response</h1>");此实现会出现乱码,因为获取的流的默认编码为IOS-8859-1

乱码问题


上一个代码实现会出现乱码问题
解决方法:在获取流之前设置编码和web解码方式
   //1.设置response的编码格式(默认为IOS-8859-1)
   //response.setCharacterEncoding("编码格式")
   //2.使用response设置响应头,要求使用特定的编码格式去解码
   response.setHeader("content-type","text/html;charset=编码格式")
简单方法:
   response.setContentType("text/html;charset=编码格式")
   
   注意:使用语句2,就可以设置编码格式,和浏览器的解码格式.第1步就可以不用写了



作者:黑马程序员JavaEE培训学院
首发:http://java.itheima.com/

分享到:
在线咨询 我要报名
和我们在线交谈!