web服务器收到客户端http请求,会针对每一次请求,分别创建一个代表请求的request对象,和代表响应的
response对象。
Request对象:获取客户端哪边传送过来的的数据
Response对象:向客户端输出数据.
一、HttpServletResponse对象的介绍
Interface HttpServletResponse
public interface HttpServletResponse
extends ServletResponse(子接口)
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,
发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
二、HttpServletResponse常用的方法
1、负责向客户端发送响应的方法(父接口的方法)
response.getWriter();向客户端写入数据(文本输入)
PrintWriter out=response.getWriter();
out.write("哈哈哈");
response.getOutputStream();先客户端写入数据(字节输入 写二进制的文件)
OutputStream out=response.getOutputStream();
out.write("哈哈".getBytes());
2、负责向客户端(浏览器)发送响应头的方法
--void addDateHeader(java.lang.String name, long date)
Adds a response header with the given name and date-value.
--void addHeader(java.lang.String name, java.lang.String value)
Adds a response header with the given name and value.
--void addIntHeader(java.lang.String name, int value)
Adds a response header with the given name and integer value.
--boolean containsHeader(java.lang.String name)
Returns a boolean indicating whether the named response header has already been set.
3、负责向浏览器发送响应状态的相关方法:
--void setStatus(int sc)
Sets the status code for this response.
4、响应状态码的常量:
--static int SC_NOT_FOUND
Status code (404) indicating that the requested resource is not available.
--static int SC_OK
Status code (200) indicating the request succeeded normally.
--static int SC_INTERNAL_SERVER_ERROR
Status code (500) indicating an error inside the HTTP server which prevented it from fulfilling the request.
三、HttpServletResponse对象的常见应用:
1、使用OutputStream流向客户端输出中文数据
使用OutPutStraeam流输出中文的编码问题:
在服务器端,数据是通过哪个码表输出的,那么要控制客户端使用哪种码表解读:
outputStream.write("哈哈".getBytes("K"),);K 码表
服务端是以K码表输出的所以客户端必须使用K码表来解读:
--客户端自己选择码表解读的方式
--服务端通过设置响应头的方式来控制码表解读
response.setHeader("contene-type","text/html;charset=K");
package com.luther.servlet;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class response extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
OutputStream outputStream=resp.getOutputStream();
//getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
byte[] data="哈哈".getBytes("GBK");
resp.setHeader("content-type", "text/html;charset=GBK");
outputStream.write(data);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2、使用PrintWriter来输出中文的编码问题:
PrintWriter out=response.getWriter();
resp.setCharacterEncoding(K);//表示的是服务端以K的编码向客户端输出,所以客户端应该以K编码表来解析
response.setHeader("contene-type","text/html;charset=K");//设置客户端解析服务端传过来的信息的解码方法
3、使用PrintWriter或者OutputStream来输出数字;
OutputStream:
Error:
outputStream.write(1);
Right:
outputStream.write(1+"".getBytes(K));
tips:开发过程中如果希望服务器输出什么,客户端浏览器上面就显示什么必须要一String的形式输出.
PrintWriter:
out.write(1+"");//我们应该把1设置为字符串类型
4、文件下载:
--获取要下载的文件的绝对路径(this是指HttpServlet 它是指tomcat下的一个应用 比如test下)
servletContext接口是Servlet中最大的一个接口,呈现了web应用的Servlet视图。ServletContext实例是通过 getServletContext()方法获得的,由于HttpServlet继承GenericServlet的关系,GenericServlet类和HttpServlet类同时具有该方法。
String realPath=this.getServletContext.getRealPath("/download/哈哈哈.jpg");//获取绝对路径
--获取要下载的文件名(C:\a\b\lss)
String fileName=realPath.subString(realPath.lastIndexof("\\")+1);获取到哈哈哈
这里使用的subString()函数来切取文件名和realPath.lastIndexof("\\")获取到最后一个\的位置。
--设置浏览器以下载的形式打开文件
response.setHeader("content-disposition","attacment;fileName="+URLEncoder.encode(fileName,"utf-8"));
URLEncoder.encode(fileName,"K");是以UTF-8来设置文件名的编码格式,来防止中文文件名的乱码。
--获取文件读取流
--获取文件输入流
--创建数据缓冲区
--写入到缓冲区
--写入到客户端浏览器
Tips:
----中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),
否则会出现文件名乱码。
----在编写下载文件功能时,要使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,
可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。
package com.luther.servlet;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.w3c.dom.ls.LSSerializer;
public class responseDownloda extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
download(resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, resp);
}
public void download(HttpServletResponse resp) throws IOException {
String realPath=this.getServletContext().getRealPath("/download/哈哈哈.jpg");
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
resp.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));//以下载的形式打开
InputStream in = new FileInputStream(realPath);
int len = 0;
byte[] buffer = new byte[1024];
OutputStream out = resp.getOutputStream();
while ((len = in.read(buffer)) > 0) {
out.write(buffer,0,len);
}
in.close();
}
}
5、文件压缩
主要方法:
1、生成一个带缓存的流
ByteArrayOutputStream bout=new ByteArrayOutputStream();
ByteArrayInputStream bais=new ByteArrayInputStream();
2、调用压缩文件的类
GZIPOutputStream gzip=new GZIPOutputStream(bout);//这是生成一个压缩流并且g给他一个压缩后储存数据的输出流
gzip.write(data.getBytes("utf-8"));把数据压缩后,储存到带缓存的流里,压缩的是字节流,所以要转为字节流
3、得到压缩后的数据
byte g[]=bout.toByteArray();//转为字节数组
package com.luther.ServletStudy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.print.attribute.ResolutionSyntax;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HttpGZIP extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String data = "一粒尘埃随风飘飘荡荡" +
"风停落花上和她一起芬芳" +
"被鼻尖托起又浸在眼泪 里忧伤" +
"钻进书里的时候 闻过书香" +
"热烈地旋转在一张唱片上" +
"阳光下飞舞后随着一只鞋在街上闲逛" +
"被吹起 又被掸落" +
"被吸入 也被排放" +
"没有意义 无所谓方向不想怎样" +
"有段时间只在黑暗中张望" +
"也曾经在钻石上熠熠发亮" +
"一粒尘埃在尘世中的日子 就这样" +
"被吹起 又被掸落" +
"被吸入 也被排放" +
"没有意义 无所谓方向" +
"不想怎样" +
"被吹起 被掸落" +
"被吸入 被排放" +
"没有意义 无所谓方向" +
"不想怎样";
System.out.println("原始数据的大小为:" + data.getBytes().length);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout); //buffer
gout.write(data.getBytes("utf-8"));//把压缩后的数据输入到缓存数组中
gout.close();
//得到压缩后的数据
byte g[] = bout.toByteArray();
resp.setHeader("Content-Encoding", "gzip");//设置压缩的格式
resp.setHeader("Content-Length",g.length +"");//大小
resp.getOutputStream().write(g);//写入到页面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, resp);
}
}
6、生成验证码图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证码的表单检验</title>
</head>
<body>
<script type="text/javascript">
function ChangeCode() {
window.document.getElementById("change").src="http://localhost:8989/CodeServlet?time="+new Date().getTime();
}
</script>
<form method="get" action="http://localhost:8989/Login">
<table name="tab1" align="center">
<tr>
<td>UserName:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>请输入验证码:</td>
<td><input type="text" name="yzm"></td>
</tr>
<tr>
<td colspan="2"><a href="javascript://" > <img src="Http://localhost:8989/CodeServlet" id="change" onclick="ChangeCode()" ></a></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"></td>
</tr>
</table>
</form>
</body>
</html>
package com.luther.TestWeb;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class CodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
final long serialVersionUID = 3038623696184546092L;
//设置每四秒刷新网页
resp.setHeader("refresh", "4");
//设置以打开图片的格式打开
resp.setHeader("content/type", "image/jpeg");
//实例化图片缓存流对象 参数依此是宽 高 图像颜色的色素的格式类型
BufferedImage bImage=new BufferedImage(150, 50, BufferedImage.TYPE_INT_RGB);
//获得绘图对象
Graphics graphics=bImage.getGraphics();
//画一个实心的矩形
graphics.fillRect(0, 0, 200, 70);
//设置图片的背景颜色
graphics.setColor(Color.PINK);
//显示的字符
String str="hwerhweirhweirh3452342342387935weiewrwerwehrw";
char ch[]=str.toCharArray();
Random random=new Random();
//设置字体的大小与格式
graphics.setFont(new Font("", Font.ITALIC, 50));
StringBuffer sbBuffer=new StringBuffer();
for(int i=0;i<6;i++) {
String data=ch[random.nextInt(str.length())]+"";
sbBuffer.append(data);
//随机设置字体的颜色
graphics.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
//将字符画到图片上 一次x坐标与y坐标
graphics.drawString(data, i*(random.nextInt(10)+20), random.nextInt(30)+30);
}
for(int i=0;i<30;i++) {
//绘画30条随机的线条
graphics.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
//两个端点的坐标
graphics.drawLine(random.nextInt(256), random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
HttpSession session=req.getSession();
session.setAttribute("code",sbBuffer.toString());
session.setAttribute("date",System.currentTimeMillis());
//将图片写给浏览器
ImageIO.write(bImage, "JPG", resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, resp);
}
}
package com.luther.TestWeb;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class Login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("content-type","text/html;charset=UTF-8");
String userName=req.getParameter("username");
String password=req.getParameter("password");
String code=req.getParameter("yzm");
HttpSession session =req.getSession(false);
String rightCode=(String)session.getAttribute("code");
req.removeAttribute("code");
if(code.equalsIgnoreCase(rightCode)){
resp.getWriter().print("你好厉害呀");
}else{
resp.getWriter().print("看看哪里错误了");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}