在一定范围内 存储信息的对象 我们称为域对象
关键字ServletContext
ServletContext 范围:整个程序中 都可以访问到 并且只有一个 为单例对象
如何获取ServletContext对象?
1. 从ServletConfig对象中获取
2. 方式二:从父类中直接获取
代码示例:
web.xml 配置示例:
<servlet>
<servlet-name>demo01servlet-name>
<servlet-class>com.lanou.Demo01servlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>jamesparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>demo01servlet-name>
<url-pattern>/demo01url-pattern>
servlet-mapping>
Demo01.java
第一种方式
public class Demo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 从ServletConfig对象中获取
ServletContext application = this.getServletConfig().getServletContext();
// 添加一个数据到context域中
// 相当于添加一个键值对 key value
application.setAttribute("usename", "james");
}
}
第二种方式
public class Demo06 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object attribute = this.getServletContext().getAttribute("usename");
System.out.println(attribute);
}
}
web.xml
param>
<param-name>keyparam-name>
<param-value>Tomparam-value>
param>
和获取域对象的表现形式很相像 也是两种获取方式 分别是从父类(ServletContext)中 获取 和 ServletConfig 中获取
public class Demo01 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// fun1();
// 获取域对象
// 获取全局配置信息
ServletContext application = this.getServletContext();
String parameter = application.getInitParameter("key");
System.out.println(parameter);
}
public void fun1() {
// 先获取config对象
ServletConfig config = this.getServletConfig();
// 取出servlet的配置信息
String parameter = config.getInitParameter("username");
System.out.println(parameter);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
首先 我们在文本目录上创建 a.properties 文件 在里面写入key=aaaa
执行下面代码
public class Demo02 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取a文件
ServletContext application = this.getServletContext();
// 获取服务器上的真实路径(绝对路径)
String realPath = application.getRealPath("/WEB-INF/classes/a.properties");
// System.out.println(realPath);
// 读取文件
Properties properties = new Properties();
properties.load(new FileInputStream(realPath));
System.out.println(properties.getProperty("key"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
// 注意!获取的路径为绝对路径 如果根据工程目录下的地址填写的话
// 会报文件未找到错误 需要填写服务器 上的相对路径地址!
什么是请求转发?或者说请求转发是怎么完成的?
举一个简单的例子 小明向小王借钱 但是小王目前没有钱 小王向自己好朋友小李来借钱 小李把钱借给小王 小王又把钱借给小明 这个过程就是请求转发 小明就相当于浏览器 小王和小李就相当于servlet类 小明并不知道最终是小李的帮忙 同样的浏览器也不知道是哪个servlet类最终实现了请求.
代码示例:
Demo01.java
public class Demo03 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("1");
System.out.println("2");
// 获取域对象
ServletContext application = this.getServletContext();
// 获取转发器
RequestDispatcher dispatcher = application.getRequestDispatcher("/demo02");
// 进行请求转发
dispatcher.forward(request, response);
System.out.println("4");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Demo02.java
public class Demo04 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("3");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
// 最终打印结果为:
1
2
3
4
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象
HttpServletResponse类是一个接口
分为:
1. 响应行 协议 状态码
2. 响应头 告诉浏览器 我要做什么 例如响应给你的文件是需要下载的
3. 响应体 响应回浏览器的数据
代码示例:
public class Demo05 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 响应给浏览器一句话
// 设置服务器编码格式 默认Tomcat编码格式 iso-8859-1
// response.setCharacterEncoding("UTF-8");
// 告诉浏览器 要使用什么编码格式来查看 以什么编码格式解析数据
// 添加响应头
// response.setHeader("Content-type", "text/html;charset=UTF-8");
// 两句合并一句
response.setContentType("text/html;charset=UTF-8");
// 从响应对象 HttpServletResponse 中 获取流对象
// 注意:这个流对象不是你自己创建的 要从响应中获取
PrintWriter out = response.getWriter();
// 注意 这个流因为是系统创建的 所以不需要关闭
out.write("累死了");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
如何下载服务器上的资源?
用户通过请求发生给servlet类 servlet类处理请求 把 服务器上的图片 以流的形式使用response响应给用户的浏览器
代码示例:
public class Demo06 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// content-disposition attachment;filename=
// 从服务器中读取图片
// 边读边写
// 如果只是单纯的把图片响应回去 浏览器并不知道你要干啥(下载 或者 浏览)
// 需要通过响应头通知浏览器 这个文件具体的做法是什么!
// 获取服务器上的图片路径
ServletContext application = this.getServletContext();
String path = application.getRealPath("/WEB-INF/classes/团子大家族.png");
// 字符串切割 获取图片名字
String[] split = path.split("/");
String filename = split[split.length - 1];
// 修改文件名字的字符集
filename = new String(filename.getBytes(), "iso-8859-1");
// 添加响应头(需要拼接文件的名字)
response.setHeader("content-disposition", "attachment;filename=" + filename);
// 告诉浏览器 文件下载的格式 添加响应头
response.setHeader("content-type", "image/png");
FileInputStream fis = new FileInputStream(path);
// 注意需要 获取response 中的字节流
ServletOutputStream sos = response.getOutputStream();
int len = 0;
byte[] b = new byte[1024];
while ((len = fis.read(b)) !=-1) {
// 输出到浏览器
sos.write(b, 0, len);
}
// 注意关闭流 谁创建的流谁关!
fis.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
// 为什么要修改文件吗的字符集?
// 因为默认的字符集在浏览器中会显示乱码
// 响应头中的字符是固定的吗?
// 是固定的 需要按照规定的书写方式书写
什么是请求重定向?
还是刚刚的请求转发的例子
小明向小王借钱 但是小王目前没钱 小王直接告诉小明 我没钱 但是我的朋友小李有钱 你找他吧 于是
小明找到了小李商讨借钱的事情
代码示例:
public class Demo07 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// fun1(response);
// fun2(response);
// fun3(response);
}
public void fun3(HttpServletResponse response) throws IOException {
// 三秒后 跳转网址
response.setContentType("text/html;charset=UTF-8");
response.setHeader("refresh", "3;url=http://www.baidu.com");
response.getWriter().write("3秒钟后跳转");
}
public void fun2(HttpServletResponse response) throws IOException {
// 添加刷新头(每秒刷新1次)
response.addIntHeader("refresh", 1);
// 添加随机数
response.getWriter().write(Math.random() + "");
}
// 通过添加请求头的方式做到请求重定向
public void fun1(HttpServletResponse response) {
// 添加重定向响应头 注意要添加工程名
response.setHeader("location", "/sh-web-servlet02/demo05");
// 302重定向又称之为302代表暂时性转移 标识重定向
response.setStatus(302);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象
类似的 请求也分为三个
请求行
请求头
请求体
接下来做一些简单的小示例:
创建一个index.html
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
<form action="/sh-web-servlet02/demo08" method="get">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<button type="submit" value="提交">提交button>
form>
body>
html>
public class Demo08 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求的网址
// /sh-web-servlet02/demo08
// System.out.println(request.getRequestURI());
// http://localhost:8080/sh-web-servlet02/demo08
// System.out.println(request.getRequestURL());
// 获取请求的类型 GET 用浏览器直接回车请求的都是GET请求
// System.out.println(request.getMethod());
// 获取请求的路径(相对路径) /sh-web-servlet02
// System.out.println(request.getContextPath());
// 获取请求中携带的参数
// 参数 提交表单时name的属性
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username + " " + password);
// 判断浏览器
// 可以通过请求头中的信息 获取用户使用浏览器
String header = request.getHeader("User-Agent");
if (header.toLowerCase().contains("chrome")) {
System.out.println("正在使用谷歌浏览器");
}else if (header.toLowerCase().contains("firefox")) {
System.out.println("正在使用火狐浏览器");
}else {
System.out.println("正在使用其他浏览器");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}