Servlet学习笔记

95 阅读10分钟

B/S架构的概念

B/S架构(Browser/Server,浏览器/服务器模式),是互联网兴起后的软件体系结构,该结构将 系统功能实现的主要业务逻辑集中到服务器端,极少数业务逻辑在浏览器实现,浏览器通常负责完 成与用户的交互任务,服务器通常负责数据的管理。

JavaWeb

使用Java语言进行动态Web资源开发技术的统称

Tomcat服务器

Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP 

  • bin 主要存放二进制可执行文件和脚本
  • conf 主要存放各种配置文件
  • lib 主要用来存放Tomcat运行需要加载的jar包
  • logs 主要存放Tomcat在运行过程中产生的日志文件
  • temp 主要存放Tomcat在运行过程中产生的临时文件
  • webapps 主要存放应用程序,当Tomcat启动时会去加载该目录下的应用程序
  • work 主要存放tomcat在运行时的编译后文件

启动服务  使用bin目录下的批处理文件startup.bat来启动Tomcat服务器

关闭服务  使用bin目录下的批处理文件shutdown.bat来关闭Tomcat服务器

启动信息乱码的处理方式

conf/logging.properties文件修改为 java.util.logging.ConsoleHandler.encoding = GBK

配置文件

server.xml文件是服务器的主配置文件,可以设置端口号、设置域名或IP、默认加载的项目、请求编码

<Connector port="8888" protocol="HTTP/1.1"
       connectionTimeout="20000"
       redirectPort="8443" />

Servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,是Java语言编写 的服务器端程序,换句话说,Servlet就是运行在服务器上的Java类。 

Servlet用来完成B/S架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态Web内容。

步骤

建立一个Java Web Application项目并配置Tomcat服务器。 

自定义类实现Servlet接口或继承 HttpServlet类(推荐) 并重写service方法。

 将自定义类的信息配置到 web.xml文件并启动项目

Servlet接口

javax.servlet.Servlet接口用于定义所有servlet必须实现的方法

GenericServlet类

javax.servlet.GenericServlet类主要用于定义一个通用的、与协议无关的servlet,该类实现了 Servlet接口

HttpServlet类

javax.servlet.http.HttpServlet类是个抽象类并继承了GenericServlet类。 
用于创建适用于网站的HTTP Servlet,该类的子类必须至少重写一个方法

  • void doGet(HttpServletRequest req, HttpServletResponse resp) 处理客户端的GET请求
  • void doPost(HttpServletRequest req, HttpServletResponse resp) 处理客户端的POST请求
  • void service(HttpServletRequest req, HttpServletResponse resp) 根据请求决定调用doGet还是 doPost方法

Servlet 的生命周期

  • 构造方法只被调用一次,当第一次请求Servlet时调用构造方法来创建Servlet的实例。
  • init方法只被调用一次,当创建好Servlet实例后立即调用该方法实现Servlet的初始化。
  • service方法被多次调用,每当有请求时都会调用service方法来用于请求的响应。
  • destroy方法只被调用一次,当该Servlet实例所在的Web应用被卸载前调用该方法来释放当前占用 的资源。

ServletRequest接口

主要用于向servlet提供客户端请求信息,可以从中获取到任何 请求信息

Servlet容器创建一个ServletRequest对象,并将其作为参数传递给Servlet的service方法

  • String getParameter(String name) 以字符串形式返回请求参数的值,如果该参数不存在,则返回空值
  • String[] getParameterValues( String name) 返回一个字符串对象数组,其中包含给定请求参数所具有的所有 ,如果该参数不存在,则返回空值 Enumeration
  • Map<String, String[]> getParameterMap() 返回请求参数的键值对,一个键可以对应多个值
  • String getRemoteAddr() 返回发送请求的客户端或最后一个代理的IP地址
  • int getRemotePort() 返回发送请求的客户端或最后一个代理的端口号

HttpServletRequest接口

  • javax.servlet.http.HttpServletRequest接口是ServletRequest接口的子接口,主要用于提供HTTP 请求信息的功能

  • 可直接通过HttpServletRequest对象提供的一系列get方法获取请求头数据

  • String getRequestURI() 返回此请求的资源路径信息

  • String getMethod() 返回发出此请求的HTTP方法的名称,例如GET、POST

  • String getQueryString() 返回路径后面请求中附带的参数

  • String getServletPath() 返回此请求中调用servlet的路径部分

ServletResponse接口

javax.servlet.ServletResponse接口用于定义一个对象来帮助Servlet向客户端发送响应。 

Servlet容器创建ServletResponse对象,并将其作为参数传递给servlet的service方法。

  • PrintWriter getWriter() 返回可向客户端发送字符文本的PrintWriter对象
  • String getCharacterEncoding() 获取响应内容的编码方式
  • void setContentType(String type) 如果尚未提交响应,则设置发送到客户端响应的内容类型。内容类型 可以包括字符编码规范,例如text/html;charset=UTF-8

HttpServletResponse接口

javax.servlet.http.HttpServletResponse接口继承ServletResponse接口,以便在发送响应时提供 特定于HTTP的功能

  • void sendRedirect(String location) 使用指定的重定向位置URL向客户端发送临时重定向响应

Servlet接收中文乱码

解决POST接收乱码

request.setCharacterEncoding("utf-8")

解决GET接收乱码

// 接收到get请求的中文字符串
String name = request.getParameter("name");
// 将中文字符重新编码,默认编码为ISO-8859-1
String userName = new String(name.getBytes("ISO-8859-1"),"utf-8");

重定向

首先客户浏览器发送http请求,当web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location 地址,服务器根据此请求寻找资源并发送给客户

重定向的实现

  • void sendRedirect(String location) 用指定重定向位置URL向客户端发临时重定向响应

    // 指定转发地址 response.sendRedirect("www.baidu.com");

重定向的特点

  • 重定向之后,浏览器地址栏的URL会发生改变
  • 重定向过程中会将前面Request对象销毁,然后创建一个新的Request对象
  • 重定向的URL可以是其它项目工程

转发

一个Web组件(Servlet/JSP)将未完成的处理通过容器转交给另外一个Web组件继续处理,转发 各个组件会共享Request和Response对象

转发的实现

绑定数据到Request对象

  • Object getAttribute(String name) 将指定属性值作为对象返回,若给定名称属性不存在,则返回空值
  • void setAttribute(String name,Object o) 在此请求中存储属性值

获取转发对象 转发

  • RequestDispatcher getRequestDispatcher(String path) 返回一个RequestDispatcher对象,该对象充当位于给定路径上的资源的包装器

  • void forward(ServletRequest request, ServletResponse response) 将请求从一个servlet转发到服务器上的另一个资 源(Servlet、JSP文件或HTML文件)

    // request对象中设置属性信息 request.setAttribute("key1", "value1"); // 获取转发对象 指定目标组件 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/targetServlet"); // 转发 requestDispatcher.forward(request, response);

转发的特点

  • 转发之后浏览器地址栏的URL不会发生改变
  • 转发过程中共享Request对象
  • 转发的URL不可以是其它项目工程

重定向和转发的比较

状态管理

Web程序基于HTTP协议通信,而HTTP协议是”无状态”的协议,一旦服务器响应完客户的请求之后,就断开连接,而同一个客户的下一次请求又会重新建立网络连接。

服务器程序有时是需要判断是否为同一个客户发出的请求,多次交互作为一个整体,将多次交互所涉及的数据保存下来,即状态管理

  • 客户端管理:将状态保存在客户端。基于Cookie技术实现。
  • 服务器管理:将状态保存在服务器端。基于Session技术实现。

Cookie

客户端以“名-值”形式进行保存的一种技术

浏览器向服务器发送请求时,服务器将数据以Set-Cookie消息头的方式响应给浏览器,然后浏览器 会将这些数据以文本文件的方式保存起来

当浏览器再次访问服务器时,会将这些数据以Cookie消息头的方式发送给服务器

  • Cookie(String name, String value) 创建Cookie

  • void addCookie(Cookie cookie) 添加Cookie对象到响应

  • Cookie[] getCookies() 返回此请求中包含的所有Cookie对象

  • String getName() 返回此Cookie对象中的名字

  • String getValue() 返回此Cookie对象的数值

  • void setValue(String newValue) 设置Cookie的数值

    // 获取客户端发来的Cookie Cookie[] cookies = request.getCookies(); for (Cookie tc : cookies) { System.out.println(tc.getName() + "值为:" + tc.getValue()); tc.setValue("新的值"); } // 创建Cookie对象并添加到响应信息中 Cookie cookie = new Cookie("name", "zhangfei"); response.addCookie(cookie);

Cookie的生命周期

默认情况下,浏览器会将Cookie信息保存在内存中,只要浏览器关闭,Cookie信息就会消失

  • int getMaxAge() 返回cookie的最长使用期限(以秒为单位)

  • void setMaxAge(int expiry) 设置cookie的最长保留时间(秒)

    // 获取Cookie信息的默认使用期限 int maxAge = cookie.getMaxAge(); // 设置Cookie有效期 // 负数表示浏览器关闭后失效 0表示马上失效 cookie.setMaxAge(60*10); // 秒 600秒

Cookie的路径问题

浏览器在访问服务器时,会比较Cookie的路径与请求路径是否匹配,访问的请求地址必须符合Cookie的路径或者其子路径时,浏览器才会发送Cookie信息

  • void setPath(String uri) 设置cookie的路径信息

    cookie.setPath(request.getContextPath() + "/hello")

Cookie的特点 

  • 只用于存储少量、非敏感信息
  • 将状态数据保存在浏览器端,不安全
  • 保存数据量有限制,大约4KB左右
  • 只能保存字符串信息
  • 用户可以通过浏览器设置为禁止使用

Session

Session本意为"会话"的含义,是用来维护一个客户端和服务器关联的一种技术

浏览器访问服务器时,服务器会为每一个浏览器都在服务器端的内存中分配一个空间,用于创建一个Session对象,该对象有一个id属性且该值唯一,称为SessionId,并且服务器会将这个 SessionId以Cookie方式发送给浏览器存储

浏览器再次访问服务器时会将SessionId发送给服务器,服务器可以依据SessionId查找相对应的Session对象

  • HttpSession getSession() 返回此请求关联的当前Session,若此请求没有则创建一个

  • boolean isNew() 判断是否为新创建的Session

  • String getId() 获取Session的id

  • Object getAttribute(String name) 返回在此会话中用指定名称绑定的对象,如果没有对象在 该名称下绑定,则返回空值

  • void setAttribute(String name, Object value) 使用指定的名称将对象绑定到此会话

  • void removeAttribute(String name) 从此会话中删除与指定名称绑定的对象

    // 获取session对象 HttpSession session = request.getSession(); // 判断是否为新对象 boolean isNew = session.isNew(); // 获取id String id = session.getId(); // 设置属性 session.setAttribute("name", "hello"); // 获取属性 session.getAttribute("name"); // 删除 session.removeAttribute("name");

Session的生命周期

为了节省服务器内存空间资源,服务器会将空闲时间过长的Session对象自动清除掉,服务器默认的超时限制一般是30分钟

int getMaxInactiveInterval() 获取失效时间

void setMaxInactiveInterval(int interval) 设置失效时间

// 获取Session对象
   HttpSession session = request.getSession();
// 获取对象的默认失效时间并打印
   int maxInactiveInterval = session.getMaxInactiveInterval();
   System.out.println("默认失效时间为:" + maxInactiveInterval); // 1800
// 修改失效时间
   session.setMaxInactiveInterval(1200); // 秒

也可以通过配置web.xml文件修改失效时间

<session-config>
  <session-timeout>30</session-timeout>
</session-config>

Session的特点

  • 数据比较安全。 能够保存的数据类型丰富,而Cookie只能保存字符串
  • 能够保存更多的数据,而Cookie大约保存4KB
  • 数据保存在服务器端会占用服务器的内存空间,如果存储信息过多、用户量过大,会严重影响服务器的性能