A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 森111 中级黑马   /  2018-12-29 15:04  /  863 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2019-1-4 09:16 编辑

Servlet概念
server applet 运行在服务器上的小程序
  • Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则
  • 将来我们自定义一个类,实现Servlet接口,复写方法

快速入门
  • 创建JavaEE项目
  • 定义一个类,实现Servlet接口
  • 实现接口中的抽象方法
  • 配置Servlet:在web.xml中配置

    <!--配置Servlet-->
   
[Java] 纯文本查看 复制代码
<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] 纯文本查看 复制代码
@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步就可以不用写了

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马