Java Servlet response 请求详解

域对象

在一定范围内 存储信息的对象 我们称为域对象
关键字 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

HttpServletResponse

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);
    }
}

HttpServletRequest

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);
    }
}

你可能感兴趣的:(java)