欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HttpServletResponse和HttpServletRequest

程序员文章站 2022-06-19 11:30:18
...

HttpServletResponse对象

在去发送一个请求时, 会找到tomcat引擎,引擎会找到对应的web应用,并且会创建request对象和response对象,找到应用后, 会执行应用的web.xml再去根据url-patten的内容创建Servlet对象,并且会调用Servlet对象的service方法,并且把创建的request对象和response对象传入到方法当中
对应response对象, 自己可以往响应当中写入一些自己给客户端的内容,通过response.getwrite().wirte(“写的内容”)方法进行写入,写的内容,是存到一个response缓冲区当中,当方法执行结束之后, tomcat就会从response缓冲区当中取出数据HttpServletResponse和HttpServletRequest

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
HttpServletResponse和HttpServletRequest

① 负责向客户端(浏览器)发送数据的相关方法
HttpServletResponse和HttpServletRequest
要注输出中文的时候中文乱码问题

在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,可以通过设置响应头控制浏览器的行为,设置浏览器编码

对于OutputStream的中文编码(outputStream.write()一次只能写一个字符)

public class Servlet extends HttpServlet {
    //定义ServletConfig对象来接收配置的初始化参数
    private ServletConfig servletConfig;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //将ServletConfig对象传递给servlet
        this.servletConfig = servletConfig;
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取OutputStream输出流
        ServletOutputStream outputStream = resp.getOutputStream();
        //通过设置响应头控制浏览器以UTF-8的编码显示数据
        resp.setHeader("content-type", "text/html;charset=UTF-8");
        String data = "中国";
        /**
        * data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,
        * 如果是中文的操作系统环境,默认就是查找查GB2312的码表,
        * 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字
        * 比如: "中"在GB2312的码表上对应的数字是98
        *         "国"在GB2312的码表上对应的数字是99
        */
        /**
         * getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
         */
         byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
        /**
        outputStream.write()一次只能写一个字符
         */
         outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }


}

对于PrintWriter

response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
/**
* PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
* 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
*/
PrintWriter out = response.getWriter();//获取PrintWriter输出流
//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
response.setHeader("content-type", "text/html;charset=UTF-8");
out.write(data);

② 负责向客户端(浏览器)发送响应头的相关方法
HttpServletResponse和HttpServletRequest
③ 负责向客户端(浏览器)发送响应状态码的相关方法
HttpServletResponse和HttpServletRequest
④ 响应状态码的常量
  HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:

状态码404对应的常量
HttpServletResponse和HttpServletRequest
  状态码200对应的常量
HttpServletResponse和HttpServletRequest
  状态码500对应的常量
HttpServletResponse和HttpServletRequest
  
⑤ Response可以实现文件下载功能
javaweb学习总结(七)——HttpServletResponse对象(一)
注意:
使用OutputStream 和 PrintWriter流都可以实现但是最好使用OutputStream流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失
如果下载的是中文文件文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, “字符编码”)),否则会出现文件名乱码。

public class Servlet extends HttpServlet {
    //定义ServletConfig对象来接收配置的初始化参数
    private ServletConfig servletConfig;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //将ServletConfig对象传递给servlet
        this.servletConfig = servletConfig;
        super.init(servletConfig);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //下载web/dowmload/下载资源.jpg
        //获取下载的绝对地址
        String realPath = this.getServletContext().getRealPath("/download/下载资源.jpg");
        //获取要下载的文件名
        //lasstIndexOf(str)返回最后一次出现str的索引
        //.substring(firstIndex, lastIndex)截取指定字符串的firstIndex到lastIndex
        //\download\下载资源.jpg
        String filename = realPath.substring(realPath.lastIndexOf("\\")+1);
        //设置content-disposition响应头控制浏览器以下载的形式打开文件
        //中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
        resp.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(filename, "UTF-8"));
        //获取文件的输入流
        FileInputStream fileInputStream = new FileInputStream(realPath);
        int len = 0;
        //缓冲
        byte[] buffer = new byte[1024];
        ServletOutputStream outputStream = resp.getOutputStream();
        while((len = fileInputStream.read(buffer)) > 0){
            outputStream.write(buffer,0,len);
        }
        fileInputStream.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }


}

⑥ 使用HttpServletResponse生成验证码
使用Servlet生成验证码图片

⑦ 实现重定向

请求重定向指:一个web资源收到客户端请求后,通知客户端(浏览器)去访问另外一个web资源,这称之为请求重定向。

应用场景:用户登陆,用户首先访问登录页面,登录成功后,就会跳转到某个页面,这个过程就是一个请求重定向的过程

实现方式:response.sendRedirect(Stringlocation),即调用response对象的sendRedirect方法实现请求重定向

sendRedirect内部的实现原理:使用response设置302状态码和设置location响应头实现重定向

HttpServletResponse和HttpServletRequest
是两次请求,浏览器地址栏会发生变化
实现请求重定向

public class ResponseDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 1.调用sendRedirect方法实现请求重定向,
         * sendRedirect方法内部调用了
         * response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
         * response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
         */
        response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
        
        //2.使用response设置302状态码和设置location响应头实现重定向实现请求重定向
        //response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
        //response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

HttpServletRequest对象

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息

HttpServletRequet介绍

① 获取客户机信息

String requestUrl = request.getRequestURL().toString();//得到请求的URL地址
        
String requestUri = request.getRequestURI();//得到请求的资源
        
String queryString = request.getQueryString();//得到请求的URL地址中附带的参数
        
String remoteAddr = request.getRemoteAddr();//得到来访者的IP地址
       
 String remoteHost = request.getRemoteHost();//返回发出请求的客户机的完整主机名
        
int remotePort = request.getRemotePort();
        
String remoteUser = request.getRemoteUser();
        
String method = request.getMethod();//得到请求URL地址时使用的方法
        
String pathInfo = request.getPathInfo();//返回客户机所使用的网络端口号
        
String localAddr = request.getLocalAddr();//获取WEB服务器的IP地址
       
String localName = request.getLocalName();//获取WEB服务器的主机名

② 获取请求头

③ 获取客户机提交参数
获取一个参数:getParameter(String)方法(常用)
获取多个参数(复选框),返回数组:getParameterValues(String name)方法(常用)
getParameterNames()方法(不常用)
getParameterMap()方法(编写框架时常用)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>Html的Form表单元素</title>
</head>
    <legend>Html的Form表单元素</legend>
    <!--form表单的action属性规定当提交表单时,向何处发送表单数据,method属性指明表单的提交方式,分为get和post,默认为get-->
    <form action="${pageContext.request.contextPath}/demo/ServletDemo1" method="post">

        用户名(文本框)<input type="text" name="username" value="请输入用户名"><br>
        <!--密码框,其中所有输入的内容都以密文的形式显示-->&nbsp;&nbsp;(密码框)<!--&nbsp;表示的是一个空格-->
        <input type="password" name="userpass" value="请输入密码"><br>
        <!--单选按钮,通过checked指定默认选中,名称必须一样,其中value为真正需要的内容-->&nbsp;&nbsp;(单选框)<input type="radio" name="sex" value="男" checked><input type="radio" name="sex" value="女"><br>
        <!--下拉列表框,通过<option>元素指定下拉的选项-->&nbsp;&nbsp;(下拉框)<select name="dept">
            <option value="技术部">技术部</option>
            <option value="销售部" SELECTED>销售部</option>
            <option value="财务部">财务部</option>
        </select><br>
        <!--复选框,可以同时选择多个选项,名称必须一样,其中value为真正需要的内容-->&nbsp;&nbsp;(复选框)<input type="checkbox" name="inst" value="唱歌">唱歌
        <input type="checkbox" name="inst" value="游泳">游泳
        <input type="checkbox" name="inst" value="跳舞">跳舞
        <input type="checkbox" name="inst" value="编程" checked>编程
        <input type="checkbox" name="inst" value="上网">上网
        <br>
        <!--大文本输入框,宽度为34列,高度为5-->&nbsp;&nbsp;(文本域)<textarea name="note" cols="34" rows="5">
     </textarea>
        <br>
        <!--隐藏域,在页面上无法看到,专门用来传递参数或者保存参数-->
        <input type="hidden" name="hiddenField" value="hiddenvalue"/>
        <!--提交表单按钮,当点击提交后,所有填写的表单内容都会被传输到服务器端-->
        <input type="submit" value="提交(提交按钮)">
        <!--重置表单按钮,当点击重置后,所有表单恢复原始显示内容-->
        <input type="reset" value="重置(重置按钮)">
    </form>
    <!--表单结束-->

</body>
<!--完结标记-->
</html>
<!--完结标记-->
public class Servlet extends HttpServlet {
    //定义ServletConfig对象来接收配置的初始化参数
    private ServletConfig servletConfig;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //将ServletConfig对象传递给servlet
        this.servletConfig = servletConfig;
        super.init(servletConfig);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取普通文本框
        //<input type="text" name="username" value="请输入用户名">
        String username = req.getParameter("username");
        System.out.println("username:"+username);

        //获取单选框
        //<input type="radio" name="sex" value="男" checked>男
        //<input type="radio" name="sex" value="女">女
        String sex = req.getParameter("sex");
        System.out.println("sex:"+sex);

        //获取下拉框
        //<select name="dept">
        //    <option value="技术部">技术部</option>
        //    <option value="销售部" SELECTED>销售部</option>
        //    <option value="财务部">财务部</option>
        //</select>
        String dept = req.getParameter("dept");
        System.out.println("sept:"+dept);

        //获取复选框
        //<input type="checkbox" name="inst" value="唱歌">
        //<input type="checkbox" name="inst" value="游泳">
        //<input type="checkbox" name="inst" value="跳舞">
        //<input type="checkbox" name="inst" value="编程" checked>
        //<input type="checkbox" name="inst" value="上网">
        //获取到的是字符串数组,使用getParameterValues
        String[] insts = req.getParameterValues("inst");
        //注意: 如果前端没有传数据则insts为null
        //打印的时候要避免空指针错误
        //要先判断是不是空 再取长度,否则对null取长度报错
        for(int i =0; insts!=null&&i<insts.length;i++){
            System.out.println(insts[i]);
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

注意点:对于getParameterValues,返回值的是数组,但如果前端没有传数据返回值为null,使用时要避免空指针错误,要先判断是不是空再取长度,否则对null取长度报错

④ 中文乱码问题

1. 如果提交方式为post,想不乱码,只需要在服务器端设置request对象的编码即可,客户端以哪种编码提交的,服务器端的request对象就以对应的编码接收,比如客户端是以UTF-8编码提交的,那么服务器端request对象就以UTF-8编码接收

request.setCharacterEncoding("UTF-8");

2. 如果提交方式为get,设置request对象的编码是无效的,request对象还是以默认的ISO8859-1编码接收数据,因此要想不乱码,只能在接收到数据后再手工转换,步骤如下:

1).获取获取客户端提交上来的数据,得到的是乱码字符串,data="???è???"

String data = request.getParameter(“paramName”);

2).查找ISO8859-1码表,得到客户机提交的原始数据的字节数组

byte[] source = data.getBytes(“ISO8859-1”);

3).通过字节数组以指定的编码构建字符串,解决乱码

data = new String(source, “UTF-8”);
  
通过字节数组以指定的编码构建字符串,这里指定的编码是根据客户端那边提交数据时使用的字符编码来定的,如果是GB2312,那么就设置成data = new String(source, “GB2312”),如果是UTF-8,那么就设置成data = new String(source, “UTF-8”)

⑤ 请求转发

请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理

HttpServletResponse和HttpServletRequest
一次请求,地址栏不会变,Request是共享的

//方法1
RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");
reqDispatcher.forward(request, response);

//方法2
request.getRequestDispatcher("/test.jsp").forward(request, response);
相关标签: javaweb

上一篇: spring security

下一篇: spring security