您的位置:首页 > 理论基础 > 计算机网络

HttpServletRequest&HttpServletResponse&乱码问题

2016-12-19 19:38 471 查看
HTTP请求响应简图

请求






响应






HttpServletRequest

简述

Request是请求,将需要传给服务器的内容打包成http协议发送给服务器

请求首行  请求方式 请求路径  协议/版本号

request.getMethod(): 获取请求方式(GET和POST)

request.getRequestURI(): 获取请求路径 /项目名称/Servlet

        request.getServletPath():获取当前Servlet地址 /Servlet

        request.getContextPath():获取当前项目地址 /项目名称

        request.getScheme():获取协议 http

请求头

原始方式获得请求头

    StringgetHeader(String name)  获取String类型的请求头

    longgetDateHeader(String name)

    intgetIntHeader(String name)

    Enumeration getHeaders(Stringname)获取该请求头名称下的所有内容

    EnumerationgetHeaderNames() 获取所有请求头的名称

       

javaee封装好的方法.

    request.getContentLength():获取请求内容长度

    request.getContentType():获取请求类型

    request.getLocale(): 获取请求的语言zh_CN表示中文

    request.getQueryString():获取参数部分

    request.getRequestURL():完整请求路径

    request.getRemoteAddr():发出请求的客户机的ip地址

    request.getRemoteHost():发出请求的客户机的的主机名

    request.getRemotePort():发出请求的客户机的端口号

    request.getServerName():服务器主机名

    request.getServerPort():服务器端口号

请求空行

请求正文 表单传送过来的键值对

    见下面

应用

1.  获取表单传过来的参数

StringgetParameter 根据键获得值

MapgetParameterMap() 获取所有参数,键为String类型,值为String[]类型,获取所有键的所有值

EnumerationgetParameterNames()  获得提交的所有键

String[]getParameterValues(String name)  根据键获得值. 获得一键对应多个值的情况的.

 

2.  request的请求转发和包含功能

request.getRequestDispatcher(Stringpath)

转发:request.getRequestDispatcher(String path). forward(request,response);

        一个Servlet处理完毕交给下面的servlet(JSP)继续处理.

作用:

    在现实开发中,没有servlet转发给servlet的情况.都是由servlet转发给JSP.

    这样可以达到分工的作用:

        servlet: 比较适合处理业务.

        JSP: 比较适合显示功能

    注意问题:

        servlet中不要做 输出正文的动作,没有结果的

    如果放到前面会出现乱码.但是响应头是可以设置的.

   

包含: request.getRequestDispatcher(String path). include(request, response);

        两个servlet(jsp)共同向浏览器输出内容.

    作用:

        在现实开发中,多个页面含有相同的内容,我们把相同的内容抽取到一个jsp中,在需要显示这个段内容的jsp中,包含抽取的jsp.可以达到

        统一管理相同的内容.

 

3.防盗链(Referer头)

防盗链:

   有些下载系统的下载地址会有一个下载跳转,用户在下载页面上看到的下载地址可能是 http://www.abc.com/down.asp?id=xxxx[/code] 
    有人直接将这个地址复制到其他地方,即可盗链,直接利用下载的地址就可以实现下载,而不是通过我自己的网站去下载,这时我们就需要判断下是否是通过我自己的网站点击下载的。

   所以我们需要在 down.asp 这个页面做下简单的来源判断。如果不是来自本站的连接,则直接拒绝访问。

        String referer = request.getHeader("referer");//获取请求头  

      判断这个头是否为空,或这个头的首地址是否为自己的地址,如果不是则重定向

4.request域(servlet技术中三大域之二)

    原理:

        在request对象中含有一个map.这个map就是request域.

    作用:

        在将来开发中. 使用请求转发时,servlet处理完数据, 处理结果要交给jsp显示. 可以使用request域将处理结果有servlet带给jsp显示.

    操作:

        1.setAttribute  存入一个键值对

        2.getAttribute  通过键取出值

        3.getAttributeNames获得域中所有键

        4.removeAttribute 跟据键移除一个键值对    

    request的范围:

        一个request对象对应一个request域(map).

        系统当前有多少个request就有多少request域.

HttpServletResponse

简述

Response是响应,在服务器接收到请求之后进行处理,然后将处理结果和返回内容等信息打包成一个http协议返回给浏览器

添加状态码 和 描述

void setStatus(int sc)  只设置状态码

void setStatus(intsc, String sm)   设置状态码和描述(已经不再使用,用下面的sendError代替)

void sendError(intsc) 只设置状态码,错误的

void sendError(intsc, String msg)  设置状态码和描述

响应头

添加响应头

      void setHeader(String name, String value) 设置响应头,如果key一样会覆盖

              setIntHeader(String name, intvalue)

              setDateHeader(St
4000
ring name, longdate)

 

      void addHeader(String name, String value) 设置响应头,无论如何都新增.

               void addIntHeader(String name, int value)

               void addDateHeader(String name, longdate) 

  比如:

       response.setHeader("Refresh","5;url=/MyWeb/AServlet");

       设置响应头中的Refresh(刷新),5代表5s之后,url代表要刷新到哪个地址

response.setHeader("Content-Type","text/html;charset=utf-8");

设置浏览器显示内容的方式和编码格式,text/html代表浏览器段是以text和html

格式显示内容,编码格式为utf-8

response.setHeader("Content-Desposition","attachment;filename=1.jpg");

告知浏览器返回内容的方式和名字,attachment是以附件格式放回,filename告知保存文件以什么样的名字,就是图片显示或者文件下载

  响应正文

      发送字节流

          getOutputStream

      发送字符流

          getWriter

  就是JavaSE基础中的字节流和字符流

应用

例一: 手动向浏览器发送404  response.setStatus(404);

例二: Refresh头.刷新

例三: 重定向 

1. setStatus+Refresh

2. respons.sendRedirect(String location);

例四: 发送字节流. 发送文本.

例五: 发送字符流. 发送文本.

字符流和字节流要注意的一个问题:

    字节流和字符流一定不能同时使用.

例六:使用字节流发送图片

例七:使用字节流发送文件(文件下载)

 

 

乱码问题

乱码的产生原因只有一个,就是编码方式与解码方式不一致(解析方式不一致)

比如说,我编码方式是UTF-8(一个汉字3个字节),解码方式却是GBK(一个汉字2个字节)。假设我要处理的数据是“你好”这个字符串,以UTF-8方式编码,假设该字符串转换成二进制是这样的:01101001 1011011011001101(你)  11010111 01101011 10111101(好),那么经过GBK解码之后就变成这样了01101001 10110110  11001101 11010111 01101011 10111101,原来是以三个字节解析一次变成汉字,然后变成两个字节解析一次,破坏了原有的结构,所以会乱码。

按照我自己的理解,编码方式就是字节的解析方式,UTF-8就是从开始以3个字节解析一次,GBK 就是以2个字节解析一次,字节或者说二进制数据是不变的。

发送端设置解析格式就是称为编码,接收端设置解析格式就是解码。

浏览器端显示乱码

    是由服务端向浏览器端发送数据,服务器负责编码,浏览器负责解码

    服务端编码:

        response.setCharacterEncoding(“utf-8”);

    浏览器端解码:

1. 在服务端发送数据的时候将解码方式也发送过去(设置请求头)

response.setHeader("Content-Type","text/html;charset=utf-8");

2. 在浏览器编写解码方式

在浏览器页面的顶部写上:<meta http-equiv='Content-Type'Content='text/html;charset=utf-8'></meta>

Jsp页面中是这样的:<%@page language="java" import="java.util.*"pageEncoding="UTF-8"%>

    这样比较麻烦,所以有了一个方法,可以同时设置服务端和浏览器段的解析格式:

    response.setContentType("text/html;charset=utf-8");

服务端接收乱码

    由浏览器段负责编码,服务器负责解码

    浏览器编码:

在浏览器页面的顶部写上:<metahttp-equiv='Content-Type' Content='text/html;charset=utf-8'></meta>

Jsp页面中是这样的:<%@page language="java" import="java.util.*"pageEncoding="UTF-8"%>

    服务器解码:

在服务器存在默认的解码方式(iso-8859-1),该默认解码方式在服务器的配置文件中,如果要修改则会影响整个程序,所以不建议修改。如果不修改,那么得到的数据就会以iso-8859-1的方式进行解析,会出现乱码,但是乱码是可以转换的。刚刚也说了,编码就是字节的解析,所以只要将接收到的字符串(已经用iso-8859-1解码成乱码了)以它的解码格式(iso-8859-1)转换成字节,然后再将字节以浏览器的编码格式进行编码,就得到了想要的字符串,

1.POST请求

Post请求中调用默认的解码方式是在调用request.getParameter()获取参数的时候调用的,所以在获取参数之前,我们可以先设置服务端解码方式

request.setCharacterEncoding("utf-8");

2.GET请求

Get请求中request.setCharacterEncoding("utf-8")没用,但是字节实验了一下发现了不对劲的地方,当我在jsp页面中以UTF-8编码的时候,后台不需要解析可以直接打印出来,但是用GBK编码的时候,后台无论如何解析都是乱码。我分别以ISO-8859-1、GBK和UTF-8解析成字节,然后用GBK格式编码,都是乱码。

补充(请求转发(request.getRequestDispatcher(String path). forward(request,response))和重定向(respons.sendRedirect(String location))的区别)

区别一、RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
区别二、如果传递给HttpServletResponse.sendRedirect方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
区别三、调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
区别四、HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。
区别五、RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息