Servlet API-JSP笔记-3

一、环境

  1. Eclipse Java EE IDE for Web Developers.
    Version: Neon.1a Release (4.6.1)
  2. Apache Tomcat version: 8.0.39

二、总结知识点

2.1、认识Servlet API:

Servlet API由两个软件包组成:Javax.servlet包和Javax.servlet.http包。其中Javax.servlet包主要存放与http协议无关的一般性的servlet类,Javax.servlet.http包主要存放与http协议相关的功能的类。(两个软件包都位于Tomcat的servlet-api.jar中)

2.2、本次主要说明的东西如下:

  • Javax.servlet.http包中的接口:
    • HttpServletRequest接口:提供http请求信息。
    • HttpServletResponse接口:提供http响应。
  • Javax.servlet包中的接口:
    • ServletConfig接口:在初始化的过程中由Servlet容器使用。
    • ServletContext接口:定义Servlet用于获取来自其容器的信息的方法。
    • ServletRequest接口:向服务器提交请求。
    • ServletResponse接口:响应客户端请求。
  • Javax.servlet包中的类:
    • ServletInputStream类:用于从客户端读取二进制数据。
    • ServletOutputStream类:用于将二进制数据发送到客户端。
    • ServletException类:用于异常处理的类。
    • UnavailableException类:当servlet或filter不能用时,处理异常的类。

2.3、HttpServletRequest接口

HttpServletRequest接口对应客户端http的请求。当客户端通过http访问服务器时,http请求中的所有信息都封装在HttpServletRequest对象中,我们可以通过该对象一些方法获取很多信息,其中获取客户机信息,获取请求头信息,获取请求参数等,这主要说明这三种。

2.3.1、获取客户机信息:

  • getRequestURL方法返回客户端发出完整请求的URL
  • getRequestURI方法返回请求行中的资源名部分
  • getQueryString方法返回请求行中的参数部分
  • getRemoteAddr方法返回发出请求的客户机的IP地址
  • getMethod得到客户机请求方式
  • getContextPath获得工程虚拟目录名称

部分代码如下所示:

//URI 和 URL 区别? 
//URI获得以webroot目录开始路径 URL获得以Http协议开始完整路径
//URI 描述路径范围比URL大(URL都是URI ) /lesson9_jsp/request1 ../request1 这些路径都是URI,不是URL
public class RequestServletDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(request.getRequestURI());
// 输出:/lesson9_jsp/RequestServletDemo1
System.out.println(request.getRequestURL());
// 输出为:http://localhost:8080/lesson9_jsp/RequestServletDemo1
System.out.println(request.getQueryString());
// 输出:null
System.out.println("您的ip是:" + request.getRemoteAddr());
// 输出:您的ip是:0:0:0:0:0:0:0:1
System.out.println("您的请求方式是: " + request.getMethod());
// 输出:您的请求方式是: GET
System.out.println("工程虚拟目录:" + request.getContextPath());
// 输出:工程虚拟目录:/lesson9_jsp
System.out.println("当前资源:" + request.getServletPath());
// 输出:当前资源:/RequestServletDemo1
System.out.println("uri is:"+request.getRequestURI());
// 输出:uri is:/lesson9_jsp/RequestServletDemo1
System.out.println("当前资源: "+ request.getRequestURI().substring(request.getContextPath().length()));
// 输出:当前资源: /RequestServletDemo1
}
}

2.3.2、获取请求头信息:

  • getHeader(name)—String
  • getHeaders(String name)方法—Enumeration
  • getHeaderNames方法—Enumeration

部分代码如下:

public class RequestServletDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获得所有头信息
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
// 每个头信息 名称
String name = names.nextElement();
// 根据name 获得 value
System.out.println(name + ":" + request.getHeader(name));
}
System.out.println("--------------------------------------");
// 获得一个指定头信息
System.out.println(request.getHeader("User-Agent"));
}

2.3.3、获取请求参数:

  • getParameter(name)—String 通过name获得值
  • getParameterValues—String[]通过name获得多值checkbox
  • getParameterNames—Enumeration获得所有name
  • getParameterMap—Map<String, String[]> key :name value:多值

部分代码如下:

public class RequestServletDemo3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接收request.html 提交数据
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("name=" + name);
System.out.println("password=" + password);
// 判断name是否为空
if (name == null || name.trim().length() == 0) {
// 不合法
request.getRequestDispatcher("/request/request3.html").forward(
request, response);
return;
}
// 获得多值 属性 hobby
// 如果存在多个值 getParameter 只能获得第一个值
// url?hobby=sport&hobby=music ---- 使用getParameterValues
System.out.println(request.getParameter("hobby"));
String[] arr = request.getParameterValues("hobby");
System.out.println(Arrays.toString(arr));

// 下面通过getParameterNames 和 getParameterMap 遍历所有请求参数
System.out.println("---------------------------------------");

// 第一种通过getParameterNames
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String parameterName = names.nextElement();
String[] parameterValues = request.getParameterValues(parameterName);
System.out.println(parameterName + ":"+ Arrays.toString(parameterValues));
}

// 第二种通过 getParameterMap 遍历所有数据
Map<String, String[]> map = request.getParameterMap();
// 通过keySet entrySet两种方式遍历map
System.out.println("getParameterMap keySet----------------------");
Set<String> keySet = map.keySet();
for (String key : keySet) {
String[] values = map.get(key);
System.out.println(key + ": " + Arrays.toString(values));
}
System.out.println("getParameterMap entrySet----------------------");
Set<Entry<String, String[]>> entrySet = map.entrySet();
for (Entry<String, String[]> entry : entrySet) {
System.out.println(entry.getKey() + ": "+ Arrays.toString(entry.getValue()));
}
}
}

2.4、HttpServletResponse接口

HttpServletResponse对象提供服务器对客户端的http响应,它封装了向客户端提供数据、发送响应头、发送相应状态码等方法,这里主要说明指定状态码&头信息,状态码和头信息应用以及它生成响应等操作。

2.4.1、指定状态码&头信息以及头信息应用:

部分代码如下:

public class ResponseServletDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置状态码setStatus
// response.setStatus(404);
// response.setStatus(200);

// 重定向设置使浏览器去访问另一个WEB资源
response.setStatus(HttpServletResponse.SC_FOUND);
// 浏览器重定向,相对的和绝对的都可以
// response.setHeader("Location", "index.jsp");
// response.setHeader("Location", "/lesson9_jsp/index.jsp");
// 简化重定向
response.sendRedirect("/lesson9_jsp/index.jsp");

// 3秒后自动跳转 index.jsp
// 如果是客户端访问一个路径,此时必须 /工程名
response.setHeader("refresh", "3;url=/lesson9_jsp/index.jsp");
// 在跳转同时,提示用户页面将要跳转
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("页面将在3秒后 自动跳转index.jsp, 如果没有跳转请点击<a href='/lesson9_jsp/index.jsp'>这里</a>");

// 设置三个禁止缓存头字段
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
// 设置Expires时,一般不设置String 日期字符串 书写复杂
// 参数一个毫秒 -1毫秒 -- java中时间 从1970年1月1日 0点开始计时
// 当前网页已经过期
response.setDateHeader("Expires", -1);
}
}

2.4.2、response生成响应:

部分代码如下所示:

public class ResponseServletDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置浏览器查看编码两种方式
// setContentType 具有 setCharacterEncoding 效果
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
// getOutputStream 与 getWriter 不能同时使用

//字节流数据输出
// 下面语句报错提示:类型不匹配:不能从 HttpServletResponse 转换为 OutputStream
// OutputStream out = response。getOutputStream();

// 字符流输出
// response.getWriter().println("今天天气多云,可能有雨!");

// tomcat会自动关流
}
}

Response Notice

2.5、ServletConfig接口与ServletContext接口

2.5.1、关于ServletConfig接口:

在Servlet的配置文件中,可以使用一个或者多个标签为servlet配置一些初始化参数,当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig的对象传递给servlet,进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息,从一个servlet实例化之后,对任何客户端的任何时候访问都有效,一个servlet的ServletConfig不能被其他servlet访问。

部分代码如下所示:

public class ServletConfigDemo1 extends HttpServlet {
// private ServletConfig config;
// @Override
// public void init(ServletConfig config) throws ServletException {
// // 父类GenericServlet中已经做了this.config=config就不需要重写了,不需要覆盖带参数的初始化方法
// // this.config = config;
// // 传入一个ServletConfig 参数,获得Servlet实例初始化数据
// System.out.println("init " + config.getInitParameter("uname"));
// System.out.println("init " + config.getInitParameter("password"));
//
// // 获得所有参数name的集合
// Enumeration<String> names = config.getInitParameterNames();
// // 遍历names 获取所有初始化参数值
// while (names.hasMoreElements()) {
// String name = (String) names.nextElement();
// System.out.println("init " + name + "="
// + config.getInitParameter(name));
// }
// }
@Override
public void init() throws ServletException {
// 覆盖无参的初始化方法,config是私有的参数,就不能用了,通过getServletConfig方法获取config对象
System.out.println("init " + getServletConfig().getInitParameter("uname"));
System.out.println("init " + getServletConfig().getInitParameter("password"));
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 在doGet方法中 如何获得初始化数据 ????从init 方法传递config 到doGet
// 使用保存成员变量 config 获得初始化信息
// System.out.println("doGet " + config.getInitParameter("uname"));
// System.out.println("doGet " + config.getInitParameter("password"));

System.out.println("doGet "+ getServletConfig().getInitParameter("uname"));
System.out.println("doGet "+ getServletConfig().getInitParameter("password"));
}
}

2.5.2、关于ServletContext接口:

在WEB容器启动的时候,他会为每一个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。ServletCofig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。ServletContext对恩赫servlet,任何人在任何时间都有效,是真正的全部对象。

部分代码如下:

public class ServletContextCountDemo1 extends HttpServlet {
// 初始化访问次数0
@Override
public void init() throws ServletException {
// 在ServletContext对象中保存一个访问次数
ServletContext context = getServletContext();
// 保存一个数据
context.setAttribute("count", 0);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 每次访问获得原来访问次数+1
ServletContext context = getServletContext();
// 或者使用下面这条语句获取context
// ServletContext context = getServletConfig().getServletContext();
// 获得访问次数
int count = (Integer) context.getAttribute("count");
// 次数+1保存
count++;
context.setAttribute("count", count);
System.out.println("网站被访问次数为" + count);
// 浏览器显示中文
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("Demo1网站被访问次数为" + count);
}
}
Author: bugwz
Link: https://bugwz.com/2016/11/29/jsp-3/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.