javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

发布时间:2019-01-15 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

今天在来看一下Response容器的相关知识,其实这篇blog早就应该编写了,只是最近有点忙,所以被中断了。下面我们就来看一下Response容器的相关知识吧。Response和我们即将在后面说到的Request容器是一一对应的,他是web容器在用户每次请求服务端的时候,创建的一对容器对象,Response容器是服务端返还给客户机的一个响应内容对象容器,比如说:响应头,响应行,实体数据等信息,而Request容器对象是,代表用户请求服务端的的一个容器对象,比如客户机的请求头,请求行,以及携带的参数信息等。所以说Request容器对象和Response容器对象是一一对应的,他们两的生命周期也是一样的,就是在一次用户请求中。下面就来详细说一下Response容器对象的相关知识吧!

下面先来看一下Response对象的相关方法吧:

addCookie(Cookie cookie):这个方法是向Response容器中添加一个Cookie,然后服务器容器会自动的将这个Cookie回写给客户机的,至于Cookie的相关知识我们会在后面的文章中进行详解,这篇文章中这个方法暂时用不到。

addDateHeader(String name ,long date):这个是向客户机添加一个时间值属性的响应头信息,比如那个缓存的响应头expires

addHeader(String name,String value):这个是向客户机添加一个字符串值属性的响应头信息,比如重定向的响应头location

addIntHeader(String name ,int value):这个是向客户机添加一个字符串属性的响应头信息

containsHeader(String name):这个方法是判断是否含有这个响应头信息字段

encodeURL(String name):这个方法是用于url改写的功能的,这个和session有关,等到说session那篇文章的时候在详细说明

sendredirect(String name):这个方法是用于请求重定向的,和响应头中的location字段的作用相同

setHeader(String name,String value)/setIntHeader(String name,int value)/setDateHeader(String name,long date):这些方法和addHeader方法是相对应的,唯一和addHeader不同的是,addHeader是向Response中添加一个响应头信息,而setHeader是修改一个响应头信息的。

setstatus(int value):通过这个方法是设置响应码的,比如:200,304,404等。

getOutputStream():通过这个方法可以拿到一个字节流,然后可以向Response容器中写入字节数据,最后客户机向Response容器中拿去数据进行显示

getWrITer():通过这个方法可以拿到一个字符流(PRintWriter),然后可以向Response容器中写入字符数据,最后客户机向Response容器中拿去数据进行显示

setContentLength():通过这个方法设置服务器向用户返回的数据长度,我们在HTTP协议详解这篇bLOG中的那个压缩数据的返回的例子中有说到

setContentTyPE():方法可以直接设置响应头content-type的内容

下面我们就来详细介绍一下这些方法的使用吧:

第一个例子:通过Response进行数据的输出,下面是一个测试的方法,这个方法只要在service方法中调用即可,传递一个HttpServletResponse对象,就可以进行输出的

publicvoidtest(HttpServletResponseresponse)throwsException{

//使用OutputStream字节流进行数据的输出

response.getOutputStream().write("HelloWorld".getBytes());

}

这个例子很简单就是将字符串写到response容器中,然后客户机从容器中拿取数据进行显示即可,但是这里我们需要注意的,当我们在使用response.getOutputStream()这样获取一个Outputstream流的时候,我们在使用完之后,并不需要手动的去关闭,系统会自动关闭它,如果我们手动去关闭这个流的话,还会引发一些问题。

这里我们输出的是"Hello World"英文,使用浏览器去访问的时候是没有乱码问题,下面我们在将代码改写一下,

response.getOutputStream.write("中国".getBytes("utf-8"));

这时候我们使用浏览器去访问数据的时候,当然我们可能会看到"中国",也有可能看到的是乱码,原因很简单,如果浏览器使用的是gb2312码表打开的话,就是乱码,如果是使用utf-8码表打开的话,就是正常的数据。当然我们可以手动的去设置浏览器的打开码表,默认的是gb2312(系统默认码表),那么如果我们使用utf-8将数据写入到Response中,然后浏览器使用的是默认的码表去拿取数据进行显示,那肯定是乱码了,那么我们该怎么办呢?,让用户手动的去修改浏览器的打开码表,那貌似太恶心了,所以这里我们就要介绍一个响应头字段的作用了,Content-type:这个头就是告诉浏览器以什么方式打开数据,并且指定相应的码表,具体代码如下:[java]view plaincopy

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

这样,我们就可以告诉浏览器以utf-8码表去显示数据,这样也就不会再有乱码的问题了。

这里我们在扩展一下就是还有一种方式控制浏览器的打开码表,那就是使用

标签来实现:

response.getOutputStream().write("".getBytes()); 这里我们组建了一个标签,并将这个标签写入到Response容器中,当客户机使用去拿取这段数据的时候,发现有html中的标签所以会通过一些处理会把上面的字符串当做是是html代码来显示。这里使用了标签来解决乱码问题的。

上面使用的是字节流的方式来给客户机发送数据的,有时候我们可能会使用字符流来显示数据,因为字符流在特定场合下回比字节流更方便的输出,其实这里使用response.getWriter()来获取一个PrintWriter字符流对象,然后我们可以使用PrintWriter对象的write方法直接写字符串数据,但是这里也是需要来解决乱码的问题,而且这里的需要解决的问题比上面的字节流更麻烦。下面来看一下吧:

response.getWriter.write("中国"); 通过上面的方法进行输出,显示的是乱码,首先servlet将"中国"字符串写入到Response容器中,但是这里需要注意的一个问题就是,将"中国"写入到Response中,那么Response容器中是怎么存储"中国"字符串的,因为Response这些技都是老外发明的,所以他们肯定是使用iso8859-1编码来进行存储字节数据的,所以这里就会有一个大问题,因为我们知道iso8859-1使用的是单个字节表示一个字符的,而gb2312使用的是两个字节,utf-8使用的是三个字节,所以Response将使用iso8859-1码表进行编码,那么存储的是两个乱码字节,所以,当客户机从Response容器中去拿取数据的时候显示的肯定是乱码,那么当我们使用

response.setHeader("Content-type","text/html;charset=utf-8") 来设置浏览器的打开数据的码表,但是我们会发现还是显示两个??,这个也是很简单的,因为我们在编写JavaSE中,也会知道这个问题就是将utf-8这种多字节的码表转到低字节码表iso8859-1,当我这时候在将结果转成utf-8的数据,这时候是不可能在转回原始数据的。所以说我们应该去修改Response容器的码表,将其码表改成utf-8,这时候就可以"中国"写入到Response容器中,而且会以utf-8的码表进行存储的,当客户机在用utf-8码表打开的时候就不会有问题了,

上面我们使用字节流来进行书写数据的时候,是没有问题的,因为是将"中国"的字节数据直接写到Response容器中的,所以不会涉及到Response容器编码的问题。

所以说当我们在使用字符流写入数据的时候,我们一定要记得修改Response容器的编码,不然会出现乱码的

response.setCharacterEncoding("utf-8");

response.setHeader("content-type","text/html;charset=utf-8"); 所以要用这两行代码的,同时response对象中还有一个方法:setContentType,这个方法可以直接设置Content-type字段的值

response.setContentType("text/html;charset=utf-8"); 其实这一行代码就相当于上面的两行代码的效果,因为在setContentType方法中已经调用了setCharacterEncoding方法设置了Response容器的编码了。

下面我们在来看一下怎么通过响应头实现下载的,这里我们只是来解决一下下载的文件名是中文的情况:

下面图片就是我们没有去解决文件名是中文的问题。浏览器会过滤中文,并且浏览器会认为其是html类型的数据

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

下面我们使用URLEncoder.encode(filename,"utf-8");来将中文名进行编码

//实现下载

publicvoidtest3(HttpServletResponseresponse)throwsException{

/**

*这时候就需要通过url进行编码

*/

ServletContextcontext=this.getServletContext();

//通过context方式直接获取文件的路径

Stringpath=context.getRealPath("/download/美女.jpeg");

//获取文件名

Stringfilename=path.substring(path.lastIndexOf("//")+1);

//将文件名进行URL编码

filename=URLEncoder.encode(filename,"utf-8");

//告诉浏览器用下载的方式打开图片

response.setHeader("content-disposition","attachment;filename="+filename);

//将图片使用字节流的形式写给客户机

InputStreamis=this.getServletContext().getResourceAsStream("/download/美女.jpeg");

OutputStreamout=response.getOutputStream();

byte[]buffer=newbyte[1024];

intlen=0;

while((len=is.read(buffer))!=-1){

out.write(buffer,0,len);

}

} 处理之后的效果:

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

这次就可以正常显示文件名了,而且类型也是jpeg的类型

下面在来看一个例子,就是使用response.getOutputStream流做一个验证码图片的实现案例:

原理:首先我们使用BufferedImage对象获取一个特定高和的缓存图片,然后我们将对这个图片对象进行一些修饰加工

setBorder()来设置图片的边框

setBackground来设置图片的背景颜色

drawRandomLine来设置随机线条

drawRandomNumber来设置随机数字

然后通过响应头Content-type告诉浏览器以图片的方式打开数据

最后在使用ImageiO对象的write方法将图片写入到response.getOutputStream流中

代码如下:

 

//实现随机图片的产生

publicvoidtest4(HttpServletResponseresponse)throwsException{

finalintwidth=120;//宽

finalintheight=35;//高

BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

Graphicsg=image.getGraphics();

//设置背景色

setBackground(g,width,height);

//设置边框

setBorder(g,width,height);

//设置随机线条

drawRandomLine(g,width,height);

//设置随机数

drawRandomNumber((Graphics2D)g,width,height);

//不要缓存

/*response.setDateHeader("expires",-1);

//告诉所有浏览器不要缓存

response.setHeader("Cache-control","no-cache");

response.setHeader("Pragma","no-cache");*/

response.setHeader("content-type","image/jpeg");

ImageIO.write(image,"jpg",response.getOutputStream());

 

/**

*设置背景色

*@paramg

*@paramwidth

*@parAMHeight

*/

publicvoidsetBackground(Graphicsg,intwidth,intheight){

g.setColor(Color.WHITE);

g.fillRect(0,0,width,height);

}

/**

*设置随机线条

*@paramg

*@paramwidth

*@paramheight

*/

publicvoiddrawRandomLine(Graphicsg,intwidth,intheight){

g.setColor(Color.GREEN);

for(inti=0;i<5;i++){

intx1=newRandom().nextInt(width);

inty1=newRandom().nextInt(height);

intx2=newRandom().nextInt(width);

inty2=newRandom().nextInt(height);

g.drawLine(x1,y1,x2,y2);

}

}

/**

*设置边框

*@paramg

*@paramwidth

*@paramheight

*/

publicvoidsetBorder(Graphicsg,intwidth,intheight){

g.setColor(Color.BLUE);

g.drawRect(1,1,width-2,height-2);

}

/**

*设置随机数

*@paramg

*@paramwidth

*@paramheight

*/

publicvoiddrawRandomNumber(Graphics2Dg,intwidth,intheight){

g.setColor(Color.RED);

g.setFont(newFont("宋体",Font.BOLD,20));

//常见的中文字

//[/u4e00-/u9fa5]

Stringbase="/u7684/u4e00/u4e86/u662f/u6211/u4e0d/u5728/u4eba/u4eec/u6709/u6765/u4ed6/u8fd9/u4e0a/u7740/u4e2a/u5730/u5230/u5927/u91cc/u8bf4/u5c31/u53bb/u5b50/u5f97/u4e5f/u548c/u90a3/u8981/u4e0b/u770b/u5929/u65f6/u8fc7/u51fa/u5c0f/u4e48/u8d77/u4f60/u90fd/u628a/u597d/u8fd8/u591a/u6ca1/u4e3a/u53c8/u53ef/u5bb6/u5b66/u53ea/u4ee5/u4e3b/u4F1a/u6837/u5e74/u60f3/u751f/u540c/u8001/u4e2d/u5341/u4ece/u81ea/u9762/u524d/u5934/u9053/u5b83/u540e/u7136/u8d70/u5f88/u50CF/u89c1/u4e24/u7528/u5979/u56fd/u52a8/u8fdb/u6210/u56de/u4ec0/u8fb9/u4f5c/u5bf9/u5f00/u800c/u5DF1/u4e9b/u73b0/u5c71/u6c11/u5019/u7ecf/u53d1/u5de5/u5411/u4e8b/u547d/u7ed9/u957f/u6c34/u51e0/u4e49/u4e09/u58f0/u4e8e/u9ad8/u624b/u77e5/u7406/u773c/u5fd7/u70b9/u5fc3/u6218/u4e8c/u95ee/u4f46/u8eab/u65b9/u5b9e/u5403/u505a/u53eb/u5f53/u4f4f/u542c/u9769/u6253/u5462/u771f/u5168/u624d/u56db/u5df2/u6240/u654c/u4e4b/u6700/u5149/u4ea7/u60c5/u8def/u5206/u603b/u6761/u767d/u8bdd/u4e1c/u5e2d/u6b21/u4eb2/u5982/u88ab/u82b1/u53e3/u653e/u513f/u5e38/u6c14/u4e94/u7B2C/u4f7f/u5199/u519b/u5427/u6587/u8fd0/u518d/u679c/u600e/u5b9a/u8bb8/u5feb/u660e/u884c/u56e0/u522b/u98de/u5916/u6811/u7269/u6d3b/u90e8/u95e8/u65e0/u5f80/u8239/u671b/u65b0/u5e26/u961f/u5148/u529b/u5b8c/u5374/u7ad9/u4ee3/u5458/u673a/u66f4/u4e5d/u60a8/u6bcf/u98ce/u7ea7/u8ddf/u7b11/u554a/u5b69/u4e07/u5c11/u76f4/u610f/u591c/u6bd4/u9636/u8fde/u8f66/u91cd/u4fbf/u6597/u9a6c/u54ea/u5316/u592a/u6307/u53d8/u793e/u4f3c/u58eb/u8005/u5e72/u77f3/u6ee1/u65e5/u51b3/u767e/u539f/u62ff/u7fa4/u7a76/u5404/u516d/u672c/u601d/u89e3/u7acb/u6cb3/u6751/u516b/u96be/u65e9/u8bba/u5417/u6839/u5171/u8ba9/u76f8/u7814/u4eca/u5176/u4e66/u5750/u63a5/u5e94/u5173/u4fe1/u89c9/u6b65/u53cd/u5904/u8bb0/u5c06/u5343/u627e/u4e89/u9886/u6216/u5e08/u7ed3/u5757/u8dd1/u8c01/u8349/u8d8a/u5b57/u52a0/u811a/u7d27/u7231/u7b49/u4e60/u9635/u6015/u6708/u9752/u534a/u706b/u6cd5/u9898/u5efa/u8d76/u4f4d/u5531/u6d77/u4e03/u5973/u4efb/u4ef6/u611f/u51c6/u5f20/u56e2/u5c4b/u79bb/u8272/u8138/u7247/u79d1/u5012/u775b/u5229/u4e16/u521a/u4e14/u7531/u9001/u5207/u661f/u5bfc/u665a/u8868/u591f/u6574/u8ba4/u54cd/u96ea/u6d41/u672a/u573a/u8be5/u5e76/u5e95/u6df1/u523b/u5e73/u4f1f/u5fd9/u63d0/u786e/u8fd1/u4eae/u8f7b/u8bb2/u519c/u53e4/u9ed1/u544a/u754c/u62c9/u540d/u5440/u571f/u6e05/u9633/u7167/u529e/u53f2/u6539/u5386/u8f6c/u753b/u9020/u5634/u6b64/u6cbb/u5317/u5fc5/u670d/u96e8/u7a7f/u5185/u8bc6/u9a8c/u4f20/u4e1a/u83dc/u722c/u7761/u5174/u5f62/u91cf/u54b1/u89c2/u82e6/u4f53/u4f17/u901a/u51b2/u5408/u7834/u53cb/u5ea6/u672f/u996d/u516c/u65c1/u623f/u6781/u5357/u67aa/u8bfb/u6c99/u5c81/u7ebf/u91ce/u575a/u7a7a/u6536/u7b97/u81f3/u653f/u57ce/u52b3/u843d/u94b1/u7279/u56f4/u5f1f/u80dc/u6559/u70ed/u5c55/u5305/u6b4c/u7c7b/u6e10/u5f3a/u6570/u4e61/u547c/u6027/u97f3/u7b54/u54e5/u9645/u65e7/u795e/u5ea7/u7ae0/u5e2e/u5566/u53d7/u7cfb/u4ee4/u8df3/u975e/u4f55/u725b/u53d6/u5165/u5cb8/u6562/u6389/u5ffd/u79cd/u88c5/u9876/u6025/u6797/u505c/u606f/u53e5/u533a/u8863/u822c/u62a5/u53f6/u538b/u6162/u53d4/u80cc/u7ec6";

intx=5;

for(inti=0;i<4;i++){

intdegree=newRandom().nextInt(61)-30;//newRandom().nextInt()%30;//-30---30

Stringcontent=base.charAt(newRandom().nextInt(base.length()))+"";

g.rotate(degree*Math.PI/180,x,20);

g.drawString(content,x,20);

g.rotate(-degree*Math.PI/180,x,20);

x+=30;

}

}

这里我们的随机图片中显示的是常见中文。

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

这里我们看到了,但是我们这时候点击刷新的时候,发现图片是不变的,这个很纠结的,原因也很简单,因为浏览器去拿取缓存的图片的了,所以我们要解决这个问题,我们只需要告诉浏览器不要去拿取缓存:

//不要缓存

response.setDateHeader("expires",-1);

//告诉所有浏览器不要缓存

response.setHeader("Cache-control","no-cache");

response.setHeader("Pragma","no-cache");

下面我们在来看一下缓存的问题:

缓存的问题就是涉及到了几个字段,这里面的内容很多,所以在这篇文章中就不解释了,可以参考另外一篇blog:

https://blog.csdn.net/jiangwei0910410003/article/details/22917645

下面在来看一下重定向的问题:

//请求重定向:能不用尽量不用,因为需要向服务器再发一次请求,加重server的压力,像用户登录完之后要跳转到首页、购物买完之后跳转到购物车页面

//从定向的特点:1.浏览器会向服务器发送两次请求,意味着就有2个request/response;2.用重定向技术,浏览器地址栏会发生变化

publicvoidtest7(HttpServletResponseresponse)throwsException{

//使用Http响应头实现重定向

response.setStatus(302);

response.setHeader("location","/ServletDemo/index.jsp");

//使用以下的api也是可以的,相当于执行了上面的两行代码

//response.sendRedirect("/ServletDemo/index.jsp");

} 实现重定向的话,有两种方式,第一种是通过响应头字段location和响应状态码302来实现的,第二种是直接调用response的sendRedirect方法实现的,当然最重要的是要看重定向和转发的区别:

重定向的特点:浏览器的地址栏会发生改变,用户是再次向服务器发送一次请求,这时候就相当于浏览器创建了两对Response/Request对象,

转发的特点:浏览器的地址栏不会发生改变,还是在一个请求的范围内,所以服务器不会再去创建一对Response/Request对象,始终是在一个请求内。

最后在来看一下在使用response对象的时候需要注意的问题:

就是在使用response进行输出数据的时候,我们上面讲到了使用两种方式:一种是使用字节流,一种是使用字符流;但是这两种流是不能同时操作的,否在会报异常的,这个只是在使用同一个Response对象的时候会出现这样的问题,比如你在使用转发技术的时候,在一个servlet中使用字节流写数据,然后转发到另一个servlet,在这个servlet中使用字符流写数据,那这样就会有问题,但是如果你是使用了重定向的话,就不会有这样的问题了,因为重定向的话,是在两个Response对象中。,请求行,以及携带的参数信息等。所以说Request容器对象和Response容器对象是一一对应的,他们两的生命周期也是一样的,就是在一次用户请求中。下面就来详细说一下Response容器对象的相关知识吧!

下面先来看一下Response对象的相关方法吧:

addCookie(Cookie cookie):这个方法是向Response容器中添加一个Cookie,然后服务器容器会自动的将这个Cookie回写给客户机的,至于Cookie的相关知识我们会在后面的文章中进行详解,这篇文章中这个方法暂时用不到。

addDateHeader(String name ,long date):这个是向客户机添加一个时间值属性的响应头信息,比如那个缓存的响应头expires

addHeader(String name,String value):这个是向客户机添加一个字符串值属性的响应头信息,比如重定向的响应头location

addIntHeader(String name ,int value):这个是向客户机添加一个字符串属性的响应头信息

containsHeader(String name):这个方法是判断是否含有这个响应头信息字段

encodeURL(String name):这个方法是用于url改写的功能的,这个和session有关,等到说session那篇文章的时候在详细说明

sendRedirect(String name):这个方法是用于请求重定向的,和响应头中的location字段的作用相同

setHeader(String name,String value)/setIntHeader(String name,int value)/setDateHeader(String name,long date):这些方法和addHeader方法是相对应的,唯一和addHeader不同的是,addHeader是向Response中添加一个响应头信息,而setHeader是修改一个响应头信息的。

setStatus(int value):通过这个方法是设置响应码的,比如:200,304,404等。

getOutputStream():通过这个方法可以拿到一个字节流,然后可以向Response容器中写入字节数据,最后客户机向Response容器中拿去数据进行显示

getWriter():通过这个方法可以拿到一个字符流(PrintWriter),然后可以向Response容器中写入字符数据,最后客户机向Response容器中拿去数据进行显示

setContentLength():通过这个方法设置服务器向用户返回的数据长度,我们在HTTP协议详解这篇blog中的那个压缩数据的返回的例子中有说到

setContentType():方法可以直接设置响应头content-type的内容

下面我们就来详细介绍一下这些方法的使用吧:

第一个例子:通过Response进行数据的输出,下面是一个测试的方法,这个方法只要在service方法中调用即可,传递一个HttpServletResponse对象,就可以进行输出的

publicvoidtest(HttpServletResponseresponse)throwsException{

//使用OutputStream字节流进行数据的输出

response.getOutputStream().write("HelloWorld".getBytes());

}

这个例子很简单就是将字符串写到response容器中,然后客户机从容器中拿取数据进行显示即可,但是这里我们需要注意的,当我们在使用response.getOutputStream()这样获取一个OutputStream流的时候,我们在使用完之后,并不需要手动的去关闭,系统会自动关闭它,如果我们手动去关闭这个流的话,还会引发一些问题。

这里我们输出的是"Hello World"英文,使用浏览器去访问的时候是没有乱码问题,下面我们在将代码改写一下,

response.getOutputStream.write("中国".getBytes("utf-8"));

这时候我们使用浏览器去访问数据的时候,当然我们可能会看到"中国",也有可能看到的是乱码,原因很简单,如果浏览器使用的是gb2312码表打开的话,就是乱码,如果是使用utf-8码表打开的话,就是正常的数据。当然我们可以手动的去设置浏览器的打开码表,默认的是gb2312(系统默认码表),那么如果我们使用utf-8将数据写入到Response中,然后浏览器使用的是默认的码表去拿取数据进行显示,那肯定是乱码了,那么我们该怎么办呢?,让用户手动的去修改浏览器的打开码表,那貌似太恶心了,所以这里我们就要介绍一个响应头字段的作用了,Content-type:这个头就是告诉浏览器以什么方式打开数据,并且指定相应的码表,具体代码如下:[java]view plaincopy

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

这样,我们就可以告诉浏览器以utf-8码表去显示数据,这样也就不会再有乱码的问题了。

这里我们在扩展一下就是还有一种方式控制浏览器的打开码表,那就是使用

标签来实现:

response.getOutputStream().write("".getBytes()); 这里我们组建了一个标签,并将这个标签写入到Response容器中,当客户机使用去拿取这段数据的时候,发现有html中的标签所以会通过一些处理会把上面的字符串当做是是html代码来显示。这里使用了标签来解决乱码问题的。

上面使用的是字节流的方式来给客户机发送数据的,有时候我们可能会使用字符流来显示数据,因为字符流在特定场合下回比字节流更方便的输出,其实这里使用response.getWriter()来获取一个PrintWriter字符流对象,然后我们可以使用PrintWriter对象的write方法直接写字符串数据,但是这里也是需要来解决乱码的问题,而且这里的需要解决的问题比上面的字节流更麻烦。下面来看一下吧:

response.getWriter.write("中国"); 通过上面的方法进行输出,显示的是乱码,首先servlet将"中国"字符串写入到Response容器中,但是这里需要注意的一个问题就是,将"中国"写入到Response中,那么Response容器中是怎么存储"中国"字符串的,因为Response这些技术都是老外发明的,所以他们肯定是使用iso8859-1编码来进行存储字节数据的,所以这里就会有一个大问题,因为我们知道iso8859-1使用的是单个字节表示一个字符的,而gb2312使用的是两个字节,utf-8使用的是三个字节,所以Response将使用iso8859-1码表进行编码,那么存储的是两个乱码字节,所以,当客户机从Response容器中去拿取数据的时候显示的肯定是乱码,那么当我们使用

response.setHeader("Content-type","text/html;charset=utf-8") 来设置浏览器的打开数据的码表,但是我们会发现还是显示两个??,这个也是很简单的,因为我们在编写JavaSE中,也会知道这个问题就是将utf-8这种多字节的码表转到低字节码表iso8859-1,当我这时候在将结果转成utf-8的数据,这时候是不可能在转回原始数据的。所以说我们应该去修改Response容器的码表,将其码表改成utf-8,这时候就可以"中国"写入到Response容器中,而且会以utf-8的码表进行存储的,当客户机在用utf-8码表打开的时候就不会有问题了,

上面我们使用字节流来进行书写数据的时候,是没有问题的,因为是将"中国"的字节数据直接写到Response容器中的,所以不会涉及到Response容器编码的问题。

所以说当我们在使用字符流写入数据的时候,我们一定要记得修改Response容器的编码,不然会出现乱码的

response.setCharacterEncoding("utf-8");

response.setHeader("content-type","text/html;charset=utf-8"); 所以要用这两行代码的,同时response对象中还有一个方法:setContentType,这个方法可以直接设置Content-type字段的值

response.setContentType("text/html;charset=utf-8"); 其实这一行代码就相当于上面的两行代码的效果,因为在setContentType方法中已经调用了setCharacterEncoding方法设置了Response容器的编码了。

下面我们在来看一下怎么通过响应头实现下载的,这里我们只是来解决一下下载的文件名是中文的情况:

下面图片就是我们没有去解决文件名是中文的问题。浏览器会过滤中文,并且浏览器会认为其是html类型的数据

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

下面我们使用URLEncoder.encode(filename,"utf-8");来将中文名进行编码

//实现下载

publicvoidtest3(HttpServletResponseresponse)throwsException{

/**

*这时候就需要通过url进行编码

*/

ServletContextcontext=this.getServletContext();

//通过context方式直接获取文件的路径

Stringpath=context.getRealPath("/download/美女.jpeg");

//获取文件名

Stringfilename=path.substring(path.lastIndexOf("//")+1);

//将文件名进行URL编码

filename=URLEncoder.encode(filename,"utf-8");

//告诉浏览器用下载的方式打开图片

response.setHeader("content-disposition","attachment;filename="+filename);

//将图片使用字节流的形式写给客户机

InputStreamis=this.getServletContext().getResourceAsStream("/download/美女.jpeg");

OutputStreamout=response.getOutputStream();

byte[]buffer=newbyte[1024];

intlen=0;

while((len=is.read(buffer))!=-1){

out.write(buffer,0,len);

}

} 处理之后的效果:

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

这次就可以正常显示文件名了,而且类型也是jpeg的类型

下面在来看一个例子,就是使用response.getOutputStream流做一个验证码图片的实现案例:

原理:首先我们使用BufferedImage对象获取一个特定高和宽的缓存图片,然后我们将对这个图片对象进行一些修饰加工

setBorder()来设置图片的边框

setBackground来设置图片的背景颜色

drawRandomLine来设置随机线条

drawRandomNumber来设置随机数字

然后通过响应头Content-type告诉浏览器以图片的方式打开数据

最后在使用ImageIO对象的write方法将图片写入到response.getOutputStream流中

代码如下:

//实现随机图片的产生

publicvoidtest4(HttpServletResponseresponse)throwsException{

finalintwidth=120;//宽

finalintheight=35;//高

BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

Graphicsg=image.getGraphics();

//设置背景色

setBackground(g,width,height);

//设置边框

setBorder(g,width,height);

//设置随机线条

drawRandomLine(g,width,height);

//设置随机数

drawRandomNumber((Graphics2D)g,width,height);

//不要缓存

/*response.setDateHeader("expires",-1);

//告诉所有浏览器不要缓存

response.setHeader("Cache-control","no-cache");

response.setHeader("Pragma","no-cache");*/

response.setHeader("content-type","image/jpeg");

ImageIO.write(image,"jpg",response.getOutputStream());

/**

*设置背景色

*@paramg

*@paramwidth

*@paramheight

*/

publicvoidsetBackground(Graphicsg,intwidth,intheight){

g.setColor(Color.WHITE);

g.fillRect(0,0,width,height);

}

/**

*设置随机线条

*@paramg

*@paramwidth

*@paramheight

*/

publicvoiddrawRandomLine(Graphicsg,intwidth,intheight){

g.setColor(Color.GREEN);

for(inti=0;i<5;i++){

intx1=newRandom().nextInt(width);

inty1=newRandom().nextInt(height);

intx2=newRandom().nextInt(width);

inty2=newRandom().nextInt(height);

g.drawLine(x1,y1,x2,y2);

}

}

/**

*设置边框

*@paramg

*@paramwidth

*@paramheight

*/

publicvoidsetBorder(Graphicsg,intwidth,intheight){

g.setColor(Color.BLUE);

g.drawRect(1,1,width-2,height-2);

}

/**

*设置随机数

*@paramg

*@paramwidth

*@paramheight

*/

publicvoiddrawRandomNumber(Graphics2Dg,intwidth,intheight){

g.setColor(Color.RED);

g.setFont(newFont("宋体",Font.BOLD,20));

//常见的中文字

//[/u4e00-/u9fa5]

Stringbase="/u7684/u4e00/u4e86/u662f/u6211/u4e0d/u5728/u4eba/u4eec/u6709/u6765/u4ed6/u8fd9/u4e0a/u7740/u4e2a/u5730/u5230/u5927/u91cc/u8bf4/u5c31/u53bb/u5b50/u5f97/u4e5f/u548c/u90a3/u8981/u4e0b/u770b/u5929/u65f6/u8fc7/u51fa/u5c0f/u4e48/u8d77/u4f60/u90fd/u628a/u597d/u8fd8/u591a/u6ca1/u4e3a/u53c8/u53ef/u5bb6/u5b66/u53ea/u4ee5/u4e3b/u4f1a/u6837/u5e74/u60f3/u751f/u540c/u8001/u4e2d/u5341/u4ece/u81ea/u9762/u524d/u5934/u9053/u5b83/u540e/u7136/u8d70/u5f88/u50cf/u89c1/u4e24/u7528/u5979/u56fd/u52a8/u8fdb/u6210/u56de/u4ec0/u8fb9/u4f5c/u5bf9/u5f00/u800c/u5df1/u4e9b/u73b0/u5c71/u6c11/u5019/u7ecf/u53d1/u5de5/u5411/u4e8b/u547d/u7ed9/u957f/u6c34/u51e0/u4e49/u4e09/u58f0/u4e8e/u9ad8/u624b/u77e5/u7406/u773c/u5fd7/u70b9/u5fc3/u6218/u4e8c/u95ee/u4f46/u8eab/u65b9/u5b9e/u5403/u505a/u53eb/u5f53/u4f4f/u542c/u9769/u6253/u5462/u771f/u5168/u624d/u56db/u5df2/u6240/u654c/u4e4b/u6700/u5149/u4ea7/u60c5/u8def/u5206/u603b/u6761/u767d/u8bdd/u4e1c/u5e2d/u6b21/u4eb2/u5982/u88ab/u82b1/u53e3/u653e/u513f/u5e38/u6c14/u4e94/u7b2c/u4f7f/u5199/u519b/u5427/u6587/u8fd0/u518d/u679c/u600e/u5b9a/u8bb8/u5feb/u660e/u884c/u56e0/u522b/u98de/u5916/u6811/u7269/u6d3b/u90e8/u95e8/u65e0/u5f80/u8239/u671b/u65b0/u5e26/u961f/u5148/u529b/u5b8c/u5374/u7ad9/u4ee3/u5458/u673a/u66f4/u4e5d/u60a8/u6bcf/u98ce/u7ea7/u8ddf/u7b11/u554a/u5b69/u4e07/u5c11/u76f4/u610f/u591c/u6bd4/u9636/u8fde/u8f66/u91cd/u4fbf/u6597/u9a6c/u54ea/u5316/u592a/u6307/u53d8/u793e/u4f3c/u58eb/u8005/u5e72/u77f3/u6ee1/u65e5/u51b3/u767e/u539f/u62ff/u7fa4/u7a76/u5404/u516d/u672c/u601d/u89e3/u7acb/u6cb3/u6751/u516b/u96be/u65e9/u8bba/u5417/u6839/u5171/u8ba9/u76f8/u7814/u4eca/u5176/u4e66/u5750/u63a5/u5e94/u5173/u4fe1/u89c9/u6b65/u53cd/u5904/u8bb0/u5c06/u5343/u627e/u4e89/u9886/u6216/u5e08/u7ed3/u5757/u8dd1/u8c01/u8349/u8d8a/u5b57/u52a0/u811a/u7d27/u7231/u7b49/u4e60/u9635/u6015/u6708/u9752/u534a/u706b/u6cd5/u9898/u5efa/u8d76/u4f4d/u5531/u6d77/u4e03/u5973/u4efb/u4ef6/u611f/u51c6/u5f20/u56e2/u5c4b/u79bb/u8272/u8138/u7247/u79d1/u5012/u775b/u5229/u4e16/u521a/u4e14/u7531/u9001/u5207/u661f/u5bfc/u665a/u8868/u591f/u6574/u8ba4/u54cd/u96ea/u6d41/u672a/u573a/u8be5/u5e76/u5e95/u6df1/u523b/u5e73/u4f1f/u5fd9/u63d0/u786e/u8fd1/u4eae/u8f7b/u8bb2/u519c/u53e4/u9ed1/u544a/u754c/u62c9/u540d/u5440/u571f/u6e05/u9633/u7167/u529e/u53f2/u6539/u5386/u8f6c/u753b/u9020/u5634/u6b64/u6cbb/u5317/u5fc5/u670d/u96e8/u7a7f/u5185/u8bc6/u9a8c/u4f20/u4e1a/u83dc/u722c/u7761/u5174/u5f62/u91cf/u54b1/u89c2/u82e6/u4f53/u4f17/u901a/u51b2/u5408/u7834/u53cb/u5ea6/u672f/u996d/u516c/u65c1/u623f/u6781/u5357/u67aa/u8bfb/u6c99/u5c81/u7ebf/u91ce/u575a/u7a7a/u6536/u7b97/u81f3/u653f/u57ce/u52b3/u843d/u94b1/u7279/u56f4/u5f1f/u80dc/u6559/u70ed/u5c55/u5305/u6b4c/u7c7b/u6e10/u5f3a/u6570/u4e61/u547c/u6027/u97f3/u7b54/u54e5/u9645/u65e7/u795e/u5ea7/u7ae0/u5e2e/u5566/u53d7/u7cfb/u4ee4/u8df3/u975e/u4f55/u725b/u53d6/u5165/u5cb8/u6562/u6389/u5ffd/u79cd/u88c5/u9876/u6025/u6797/u505c/u606f/u53e5/u533a/u8863/u822c/u62a5/u53f6/u538b/u6162/u53d4/u80cc/u7ec6";

intx=5;

for(inti=0;i<4;i++){

intdegree=newRandom().nextInt(61)-30;//newRandom().nextInt()%30;//-30---30

Stringcontent=base.charAt(newRandom().nextInt(base.length()))+"";

g.rotate(degree*Math.PI/180,x,20);

g.drawString(content,x,20);

g.rotate(-degree*Math.PI/180,x,20);

x+=30;

}

}

这里我们的随机图片中显示的是常见中文。

 

javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)

 

这里我们看到了,但是我们这时候点击刷新的时候,发现图片是不变的,这个很纠结的,原因也很简单,因为浏览器去拿取缓存的图片的了,所以我们要解决这个问题,我们只需要告诉浏览器不要去拿取缓存:

//不要缓存

response.setDateHeader("expires",-1);

//告诉所有浏览器不要缓存

response.setHeader("Cache-control","no-cache");

response.setHeader("Pragma","no-cache");

下面我们在来看一下缓存的问题:

缓存的问题就是涉及到了几个字段,这里面的内容很多,所以在这篇文章中就不解释了,可以参考另外一篇blog:

https://blog.csdn.net/jiangwei0910410003/article/details/22917645

下面在来看一下重定向的问题:

//请求重定向:能不用尽量不用,因为需要向服务器再发一次请求,加重server的压力,像用户登录完之后要跳转到首页、购物买完之后跳转到购物车页面

//从定向的特点:1.浏览器会向服务器发送两次请求,意味着就有2个request/response;2.用重定向技术,浏览器地址栏会发生变化

publicvoidtest7(HttpServletResponseresponse)throwsException{

//使用Http响应头实现重定向

response.setStatus(302);

response.setHeader("location","/ServletDemo/index.jsp");

//使用以下的api也是可以的,相当于执行了上面的两行代码

//response.sendRedirect("/ServletDemo/index.jsp");

} 实现重定向的话,有两种方式,第一种是通过响应头字段location和响应状态码302来实现的,第二种是直接调用response的sendRedirect方法实现的,当然最重要的是要看重定向和转发的区别:

重定向的特点:浏览器的地址栏会发生改变,用户是再次向服务器发送一次请求,这时候就相当于浏览器创建了两对Response/Request对象,

转发的特点:浏览器的地址栏不会发生改变,还是在一个请求的范围内,所以服务器不会再去创建一对Response/Request对象,始终是在一个请求内。

最后在来看一下在使用response对象的时候需要注意的问题:

就是在使用response进行输出数据的时候,我们上面讲到了使用两种方式:一种是使用字节流,一种是使用字符流;但是这两种流是不能同时操作的,否在会报异常的,这个只是在使用同一个Response对象的时候会出现这样的问题,比如你在使用转发技术的时候,在一个servlet中使用字节流写数据,然后转发到另一个servlet,在这个servlet中使用字符流写数据,那这样就会有问题,但是如果你是使用了重定向的话,就不会有这样的问题了,因为重定向的话,是在两个Response对象中。

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)全部内容,希望文章能够帮你解决javascript代码实例教程-JavaWeb学习----容器Response详解(有关responsesetCharacterEncoding和setContentType)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。