xiaomi

个人博客

小米的个人博客,欢迎交流


Servlet

概念

全称 Java Servlet (Servlet = Service + Applet),用 Java 编写的 服务器端程序,处理用户发起的请求,用于交互式浏览和生成数据,生成动态Web内容

  • 狭义的 Servlet 是指 Java 语言实现的一个接口
  • 广义的 Servlet 是指 任何实现了 Servlet 接口的类

应用

Servlet 用于扩展基于 Http协议 的 web服务器

Servlet 导入特定的属于 Java Servlet API 的包

同类技术对比

  • Servlet
    • 运行在服务端
    • 没有图形界面
  • Java applet
    • 与浏览器一起在客户端运行,当作单独文件跟网页一起发送的小程序
    • 具有很好的图形界面

quickstart

声明一个 web 服务器能认识的 Java 类

  • 创建普通 Java 类并继承 HttpServlet 类

  • 复写 service 方法 (服务器接收到请求时调用 service 方法)

配置 web.xml 使 web服务器 可以找到声明过的 Java 类

  • 在 webapp 下的 WEB-INF 文件夹下的 web.xml 文件中配置 servlet

虚拟项目名是自行命名,与 tomcat 配置上写的一致就行

  • URL | 服务器地址 : 端口号 / 虚拟项目名 / servlet 别名
    • 举个栗子:www.stu.cn:8080/manager/login
  • URI | 虚拟项目名 / servlet 别名
    • 举个栗子:manager/login

生命周期

  • 服务器启动 web.xml 加载进内存

  • 第一次调用 xxx 加载进内存,直到终止服务器时才销毁内存

  • load-on-startup 生命周期从服务器启动到服务器关闭

init 方法在servlet 第一次加载进内存时执行

destory 方法在 服务器终止时执行

Servlet方法

  • service 方法:
    • 不管是get 方式还是post 方式的请求,如果Servlet类中有service方法,则优先调用Service方法。
  • doGet 方法:
    • 在没有service方法的情况下如果是get方式的请求所调用的处理请求的方法
  • doPost 方法:
    • 在没有service 方法的情况下如果是post方式的请求所调用的处理请求的方法
  • 注意:
    • 如果在覆写的service方法中调用了父类的service方法 super . service(req, resp)
    • 则service方法处理完后,会再次根据请求方式响应的doGet和doPost方法执行。
    • 所以一般情况下,我们是不在覆写的service中调用父类的service方法的,避免出现405错误。

Servlet的常见错误

  • 404错误:资源未找到
    • 原因一:在请求地址中的servlet的别名书写错误。
    • 原因二:虚拟项目名称拼写错误
  • 500错误内部服务器错误
    • 错误一:java . lang . ClassNotFoundException: com. hrbust . servlet .ServletMothod
      • 解决:在 web.xml 中校验 servlet 类的全限定路径是否拼写错误。
    • 错误二:因为 service 方法体的代码执行错误导致
      • 解决:根据错误提示对 service 方法体中的代码进行错误更改。
  • 405错误:请求方式不支持
    • 原因:请求方式和 servlet 中的方法不匹配所造成的
    • 解决:尽量使用 service 方法进行请求处理,并且不要再 service 方法中调用父类的service

Respone对象学习

  • 作用:用来响应数据到浏览器的一个对象
  • 使用:
    • 设置响应头 setHeader(String name , String value);/ /在响应头中添加响应信息,但是同键会覆盖
      addHeader(String name , String value);//在响应头中添加响应信息,但是不会覆盖。

    • 设置响应状态

      // 自定义响应状态码
      sendError(int num, String msg);
      
  • 设置响应实体

      //响应具体的数据给浏览器
      resp. getWrite() . write(String str);
    
    • 设置响应编码格式:

      resp. setContentType( "text/ html ; charset=utf-8");
      
  • 总结:
    • service请求处理代码流程:
      • 设置响应编码格式
      • 获取请求数据
      • 处理请求数据
      • 数据库操作 (MVC思想)
      • 响应处理结果

请求乱码问题

  • 使用String进行数据:重新编码
String username = req.getParameter("form-username");
username = new String(username.getBytes("iso8859-1"),"utf-8");
  • 使用公共配置
    • get方式
      • 步骤一:req.setCharacterEncoding(“utf-8”);
      • 步骤二:再 tomcat 的目录下的conf 目录中修改 server.xml 文件 -> 在 Connector 标签中增加属性 useBodyEncodingForURI=’‘true”;
    • post方式:
      • req. setCharacterEncoding(“utf-8”);
        1. 第一步
//设置请求编码格式
req.setCharacterEncoding("utf-8");
  1. 第二步

    增加一行内容 useBodyEncodingDorURI="true"

     <Connector port="8080" protocol="HTTP/1.1" 
                connectionTimeout="20000" redirectPort="8443" 
                useBodyEncodingDorURI="true"
                />
    

Servlet流程总结

  • 浏览器发起请求到服务器(请求)
  • 服务器接受浏览器的请求,进行解析,创建request对象存储请求数据
  • 服务器调用对应的servlet进行请求处理,并将request对象作为实参传递给servlet的方法
  • servlet的方法执行进行请求处理
    • 设置请求编码格式
    • 设置响应编码格式
    • 获取请求信息
    • 处理请求信息
      • 创建业务层对象
      • 调用业务层对象的方法
    • 响应处理结果
  • Servlet的使用流程:
    • 设置请求编码格式
    • 设置响应编码格式
    • 获取请求信息
    • 处理请求信息
    • 响应处理结果
  • 数据流转流程:
    • 浏览器—–>服务器——>数据库
    • 浏览器——服务器——-数据库

请求转发

  • 作用:实现多个servlet联动操作处理请求,这样避免代码冗余,让servlet的职责更加明确。
  • 使用:
    • req. getRequestDispatcher(“要转发的地址” ). forward(req, resp);`
    • 地址:相对路径,直接书写servlet的别名即可。
  • 特点:
    • 一次请求, 浏览器地址栏信息不改变。
  • 注意:
    • 请求转发后直接 return 结束即可。

request 作用域

  • 问题:
    • 使用请求转发后,不同的Servlet之间怎么进行数据的共享 呢?
    • 或者说数据怎么从一个servlet流转给另外一个Servlet呢?
  • 解决:使用request对象的作用域

  • 使用:
request.getAttribute(Object obj)
request.setAttribute(object name,Object value);
  • 作用:
    • 解决了一次请求内的不同Servlet的数据(请求数据+其他数据)共享问题。
  • 作用域:基于请求转发,一次请求中的所有Servlet共享。

  • 注意:使用Request 对象进行数据流转,数据只在一次请求内有效。

重定向

  • 问题:
    • 如果当前的请求,Servlet 无法进行处理怎么办?
    • 如果使用请求转发,造成表单数据重复提交怎么办?
  • 解诀了表单重复提交的问题,以及当前servlet无法处理的请求的问题。
  • 使用: resp. sendRedirect(String uri);
  • 特点:
    • 两次请求,两个request对象。
    • 浏览器地址栏信息改变
    • 时机:
      • 如果请求中有表单数据,而数据又比较重要,不能重复提交,建议使用重定向
      • 如果请求被Servlet接收后,无法进行处理,建议使用重定向定位到可以处理的资源。

Cookies

  • 解决问题:发送不同请求的数据共享问题

  • 使用:

//Cookie的使用
//创建Cookie对象
Cookie c = new cookie(String name, String value);
//设置cookie(可选)
//设置有效期
c.setMaxAge(int seconds);
//设置有效路径
c.setPath(String uri)
//响应Cookie信息给客户端
resp.addCookie(c);

  • 注意:
    • 一个 Cookie 对象存储一条数据。多条数据,可以多创建几个 Cookie 对象进行存储。
  • 特点:
    • 浏览器端的数据存储技术。
    • 存储的数据声明在服务器端。
    • 临时存储:存储在浏觉器的运行内存中,浏览器关闭即失效。
    • 定时存储:设置了 Cookie 的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息。
    • 默认 cookie 信息存储好之后,每次请求都会附带,除非设置有效路径

session

  • 问题:一个用户的不同请求处理的数据共享怎么办?

  • 解诀:使用 session 技术

  • 原理:
    • 用户第一次访问服务器,服务器会创建一个 session 对象给此用户,
    • 并将该 session 对象的 JSESSIONID使用 Cookie 技术存储到浏览器中
    • 保证用户的其他请求能够获取到同一个 session 对象
    • 也保证了不同请求能够获取到共享的数据。
  • 特点:
    • 存储在服务器端
    • 服务器进行创建
    • 依赖Cookie技术
    • 作用域
      • 一次会话
      • 在 JSESSIONID 和 session 对象 不失效的情况下,作用域是整个项目内
      • 默认存储时间是 30 min
  • 使用:
    • 创建 session 对象/获取 session 对象 HttpSession hs=req. getSession();
      • 如果请求中拥有 session 标识符也就是 JSESSIONID ,则返回其对应的 session 队形
      • 如果请求中没有 session 标识符也就是 JSESSIONID ,则创建新的 session 对象,并将其 JSESSIONID 作为 cookie 数据存储到浏览器中
      • 如果 session 对象失效了,也会重新创建一个 session 对象, 并将其 JSESSIONID 存储在浏览器内存中。
    • 设置 session 存储时间
      • httpSession.setMaxInactiveInterval(int seconds);
    • 设置 session 强制失效
      • httpSession.invalidate();
    • 存储和获取数据
      • 存储 httpSession.setAttribute(String s,Object o);
      • 获取 httpSession.getAttribute(String s);
      • 注意:存储的动作和取出的动作发生在不同的请求中,但是存储在先于取出执行
  • 使用时机:

    • ​ 一般用户在登陆web项目时会将用户的个人信息存储到session中,供该用户的其他请求使用
  • session 失效处理
    • 将用户请求中的 JSESSIONID 和后台获取到的 session对象 的 JSESSIONID 进行比对
    • 一致则 session 没有失效
    • 不一致则证明 session 失效
    • 重定向到登陆页面,让用户重新登陆
  • 总结:
    • session 解决了一个用户的不同请求的数据共享问题,只要在 JSESSIONID 不失效和 session对象 不失效的情况下
    • 用户的任意请求在处理时都能获取到同一个 session对象
  • 注意:

    • JSESSIONID 存储在了 Cookie 的临时存储空间中,浏览器关闭即失效。

ServletContext

  • 问题
    • Request 解决了一次请求内的数据共享问题,session 解决了 用户不同请求的数据共享问题,那么不同的用户的数据共享该怎 么办 ?
  • 方法 :使用 ServletContext 对象
  • 作用 :解决不同用户数据共享问题
  • 获取 ServletContext 对象
  • 作用域
  • 生命周期
    • 服务器启动 –> 服务器关闭
  • 使用

ServletConfig

  • 问题

    • 如何获取在 web.xml 中给每个 servlet 单独配置的数据
  • 作用

    • ServletConfig 对象是 Servlet 的专属配置对象
    • 每个 Servlet 都单独拥有一个 ServletConfig 对象
    • 用来获取 web.xml 中的配置信息
  • 使用

    ServletConfig sc = this.getServletConfig()
    

refer

av47001339