WEB开发2--request&response

来源:互联网 发布:linux piwik 安装 编辑:程序博客网 时间:2024/05/18 12:33

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向容器输出数据,只需要找response对象就行了。


一 Response

1 常见方法
Response分为响应消息行,响应消息头和响应正文。对应Request分为请求消息行,请求消息头和请求正文。主要调用ServletResponse和HttpServletResponse类(接口)里的方法

这里写图片描述


2 常见作用

2.1 向客户端发送中文数据(解决乱码问题)

  • 以字符流的形式响应(字符串文本数据)
    response.getWriter().write(“中国”);//getWriter()返回Printwriter对象

接连出现??涓浗的问题,原因如下:

由于Tomcat服务器中默认编码方式为ISO-8859-1,不支持中文。本身解析不了“中国“,所以在向浏览器响应结果时,出现??无法识别的情况(不是乱码),方法:setCharacterEncoding(“UTF-8”),告知服务器用UTF-8的方式解析文本。
然后,重新部署后,再次向浏览器响应结果时是“涓浗”(乱码),原因是没有告知浏览器应该用UTF-8的方式编码,方法:response.setHeader(“content-type”, “text/html;charset=UTF-8”)。

其实有个更简单的方法,直接告知服务器和浏览器均用UTF-8的方式编码,当然也可以用别的编码方式,格式:response. setContentType(“text/html;charset=UTF-8”);

  • 以字节流的形式响应(二进制)

response.getOutputStream().write(“中国”.getByte());//以默认编码发送数据;getOutputStream()返回ServletOuputStream对象。

getByte(): String类中的方法,返回byte[];使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。(默认字符集就是你在安装操作系统时选择的安装语言,简体中文的编码方式是GBK)。

response.getOutputStream().write(“中国”.getByte(“UTF-8”));//以UTF-8编码向客户端发送数据,若浏览器默认GBK,会出现乱码(不一致而导致的乱码)。所以这时需要response.setContentType(“text/html;charset=UTF-8”);告知浏览器一声用UTF-8编码。

实例:
当response.setContentType(“text/html;charset=UTF-8”);
response.getOutputStream().write(“中国”.getByte());共同使用时,由于字节输出流使用默认编码(中文–GBK),不一致就会出现乱码。

注意:getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法,否则会抛异常。


2.2 实现请求重定向

定义:一个web资源收到客户端请求后,(可能由于自身无法处理等问题)通知客户端去访问另外一个web资源,这称之为请求重定向。

特点:地址栏会变,并发送2次请求。

实现方式:
response.sendRedirect()

实现原理:
302/307状态码和location头即可实现重定

注意:sendRedirect的路径参数写法,是绝对路径还是相对路径(带不带”/”)?要不要写上应用名(项目名)?如果参数为”www.baidu.com“,允许这样写吗?会发生什么?要与后面的Request的请求转发方法RequestDispatcher()参数区分开。

response.sendRedirect("/day01/ResponseDemo4");//注意重定向时,不一定定向到哪个项目里去了,故需要在引号里写上/+项目名(应用名)。表示http//localhost:8080/后面的东西。当然也可以直接写"www.baidu.com",会跳转到百度界面//sendRedirect本质上是下面方式的合并:response.setStatus(302);//307也可以,都是告诉客户端要重新定向新的资源response.setHeader("location", "/day01/ResponseDemo4");//发送响应消息头,告诉浏览器要去访问哪个URL。

3 Response重定向执行过程细节

重定向

  1. 客户端发送http请求给web服务器
  2. 若是首次访问,web服务器创建servlet(实例化,初始化);若不是,往下走(客户端访问同一个servlet,只初始化,实例化一次)。
  3. web服务器创建request和response对象。(初始时请求信息是有客户端传来的数据的,响应信息是空的)
  4. web服务器调用servlet的service(req,rep)方法。
  5. web把执行权交给servlet,先通过request获取请求信息(头,行,正文)。
  6. 然后执行程序,用sendRedirect方法,写特殊响应头,将结果保存到response对象中()
  7. servlet的service方法执行完毕,将执行权返回给web服务器。
  8. web服务器解析response对象返回值,发出包含重定向的http响应,返回给客户端。(web服务器=tomcat=servlet引擎)
  9. 客户端发送包含重定向的请求信息
  10. 然后又是一个轮回,只不过不用再创建servlet,而且执行权在servlet时,不用写特殊响应头,而是写真正的返回结果;另外web服务器返回不返回包含重定向的http响应,而是返回真正的结果。

二 Request

1 常用方法及含义
这里写图片描述

2 获取表单数据(Form)中文乱码问题

方法一:request.getParameter(name);public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        request.setCharacterEncoding("UTF-8");        String username = request.getParameter("username");        String[] hobbys = request.getParameterValues("hobby");        System.out.println(username);        for(int i=0;i<hobbys.length;i++){        System.out.println(hobbys[i]);        }    }
方法二:request.getParameterNames()private void doGet(HttpServletRequest request)            throws UnsupportedEncodingException {        request.setCharacterEncoding("UTF-8");        Enumeration names = request.getParameterNames();        while(names.hasMoreElements()){            String name = (String)names.nextElement();            String values[]=request.getParameterValues(name);            for(int i=0;values!=null&&i<values.length;i++){                System.out.println(values[i]);            }        }    }
方法三:getParameterMap()public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {                try {                User u=new User();                Map <String,String[]> map=request.getParameterMap();                for(Map.Entry<String,String[]> m: map.entrySet()){                    String key=m.getKey();                    String value[]=m.getValue();                    PropertyDescriptor pd=new PropertyDescriptor(key,User.class);//                    Method setter=pd.getWriteMethod();                    if(value.length==1){                        setter.invoke(key, value[0]);                    }                    else{                        setter.invoke(key, (Object)value);                    }                }        } catch (Exception e) {                e.printStackTrace();            }    }


3 请求转发

客户端发送请求后,服务器一个servlet无法完全处理,需要和另一个servlet协作,两者返回的结果共同响应给客户端。使用request.RequestDispatcher()方法,设置路径参数时要注意必须是绝对路径,而且只能是当前应用的servlet(类)。
这里写图片描述

  1. 客户端发送http请求
  2. 若是首次访问,servlet引擎实例化并初始化servlet,若不是直接到3
  3. servlet引擎创建请求request和响应response对象。
  4. servlet引擎调用service(req,rep)方法,传入刚创建的两个对象作为参数
  5. servlet引擎将执行权交给servlet,调用service里的doGet方法,获取请求信息
  6. servlet调用service方法中的doPost方法,写入响应信息
  7. servlet向servlet引擎返回请求转发forward命令(只能转发当前应用下的其他servlet、jsp等)
  8. servlet引擎收到forward命令后,找到请求转发地址(URI/Mapping),若是第一次访问,创建servlet2,并调用servlet2的service方法。
  9. servlet2读取请求信息
  10. 在原来响应信息基础上,追加信息的响应信息
  11. serlet2的service方法返回
  12. servlet的service方法返回
  13. servlet引擎解析响应信息
  14. servlet引擎返回响应结果给客户端

3.1 请求转发与重定向的区别

转发:地址栏不变;客户端只请求一次;servlet间可以传递数据;不可以跳转到其他应用。
重定向:地址栏变;客户端请求两次;不可以传递数据;可以跳转到其他应用。


4 请求包含

包含:Servelt(源组件)把其他web组件(目标组件)生成的响应结果包含到自身的响应结果中。

转发和请求包含的共同点
源组件和目标组件处理的都是同一个客户请求,源组件和目标组件共享同一个ServeltRequest和ServletResponse对象。
目标组件都可以为Servlet、JSP或HTML文档
都依赖 javax.servlet.RequestDispatcher接口

0 0
原创粉丝点击