响应行
public class StatusServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//手动设置http响应行中的状态码
response.setStatus(404);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
响应头
public class RefreshServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置定时刷新的头
response.setHeader("refresh", "5;url=http://www.baidu.com");
//五分钟自动跳转到百度页面
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
总结:
请求头和响应头中的键值对是有一定功能的,里面的键值对不能随意取名或赋值
键值对都为 String类型
public class Servlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//没有响应 告知客户端去重定向到servlet2
//1、设置状态码302
//response.setStatus(302);
//2、设置响应头Location
//response.setHeader("Location", "/WEB14/servlet2");
//封装成一个重定向的方法sendRedirect(url)
response.sendRedirect("/WEB14/servlet2");//客户端的地址的时候前面的斜杠一定要。不然输出的地址有误
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
总结:
response设置重定向(sendredirect(客户端地址)),request表示转发(服务器端地址)
客户端的地址的时候前面的斜杠一定要。不让输出的地址有误
方法的实参出入参数的类型一般要么是对象集合数组,基本类型(int,date,字符串)
响应体
response.getWriter().write("hello haohao...");
案例:
把图片,视屏,音频传到客户端
public class ByteServlet extends HttpServlet {
//通过输入输出流的方式吧文件从服务器传到response缓冲区中,然后会被浏览器解析
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//使用response获得字节输出流
ServletOutputStream out = response.getOutputStream();
// 在从服务器中下文件的时候使用(把文件写入到response缓冲区中)
//获得服务器上的图片
String realPath = this.getServletContext().getRealPath("a.jpg");//在文件传输的时候使用
InputStream in = new FileInputStream(realPath);
//简单的写法(把所有的数据一起读取到数组中,然后从数组中写出来)第一种读写 的思路
byte[] array=new byte[in.available()];
in.read(array);//把所有的数据一起读取到数组中,然后从数组中写出来。
out.write(array);
in.close();
out.close();
//复杂点的写法(把数据分批次一一的读取到一个固定长度的数组,然后多次从这个输出中取出数据) 第二种读取的思路
// byte[] buffer= new byte[in.available()];
// int len=0;
// while(( len=in.read())>0)
// {
// out.write(buffer, 0, len);
// }
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
总结:
输入流(inputStream)与输出流(outputStream)出入,读写看文件(程序,读入程序中来,从程序中写出)
response可以获得输出流(获得输出到resonse缓冲区的输入流),ServletOutput输出到response缓冲区的流
inputStrem,outputStream 作用:传图片视频等二进制的文件,read(buffer)返回的是int类型的数据(存入buffer的长度),而write(buffer)没有返回值
filewriter fileReader 作用:传文档 out.writer(str); 写出数据 in.read() 返回字符串类型
BufferedReader BufferedWriter 作用:加快传输 (一行一行读) readline(一行一行的读)
本地文件--程序---其他地方(本地(复制),客户端(上传,下载))
下载
public class DownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获得要下载的文件的名称
String filename = request.getParameter("filename");//a.flv
//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
//设置返回文件的类型
//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)
response.setHeader("Content-Disposition", "attachment;filename="+filename);
需要设置文件响应类型,使用response.setContentType,比如jpeg格式的图片。如果想要访问该页面时出现下载保存的窗口,使用response.setHeader("Content-Disposition", "attachment;filename="+filename.getName())函数
//获取文件的绝对路径
String path = this.getServletContext().getRealPath("download/"+filename);// 相对webapp文件下的地址 (获得文件真实的物理路径)
//获得该文件的输入流
InputStream in = new FileInputStream(path);
//获得输出流---通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
//文件拷贝的模板代码
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
//out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
///WEB14/downloadServlet?filename=a.flv 从a标签中获得参数
// response.setContentType(this.getServletContext().getMimeType(filename));
//response.setHeader("Context-Disposition","Attachment;filename="+filename);
//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)----filename="+filename 客户端默认对名字进行解码
response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
//获取文件的绝对路径
String path = this.getServletContext().getRealPath("download/"+filename);
//获得该文件的输入流
InputStream in = new FileInputStream(path);
//获得输出流---通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
//文件拷贝的模板代码
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
//out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class DownLoadServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//*******文件名称是中文的下载*******
//获得要下载的文件的名称
String filename = request.getParameter("filename");//????.jpg
//解决获得中文参数的乱码----下节课讲
filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg
//获得请求头中的User-Agent
String agent = request.getHeader("User-Agent");
//根据不同浏览器进行不同的编码
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
//问题:加被注释的那一段,下载的文件才有中文的文件名
// 如何加上模板,如何制作模板
//如何加入服务器,如何配置jdk.如果要加入新的服务器和jdk
中文文件名
String agent = request.getHeader("User-Agent");
//根据不同浏览器进行不同的编码
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
验证码的制作:
package com.itheima.checkimg;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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;
/**
* 验证码生成程序
*
*
*
*/
public class CheckImgServlet extends HttpServlet {
// 集合中保存所有成语
private List<String> words = new ArrayList<String>();
@Override
public void init() throws ServletException {
// 初始化阶段,读取new_words.txt
// web工程中读取 文件,必须使用绝对磁盘路径
String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line = reader.readLine()) != null) {
words.add(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 禁止缓存
// response.setHeader("Cache-Control", "no-cache");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", -1);
int width = 120;
int height = 30;
// 步骤一 绘制一张内存中图片
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 步骤二 图片绘制背景颜色 ---通过绘图对象
Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
// 绘制任何图形之前 都必须指定一个颜色
graphics.setColor(getRandColor(200, 250));
graphics.fillRect(0, 0, width, height);
// 步骤三 绘制边框
graphics.setColor(Color.WHITE);
graphics.drawRect(0, 0, width - 1, height - 1);
// 步骤四 四个随机数字
Graphics2D graphics2d = (Graphics2D) graphics;
// 设置输出字体
graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
Random random = new Random();// 生成随机数
int index = random.nextInt(words.size());
String word = words.get(index);// 获得成语
// 定义x坐标
int x = 10;
for (int i = 0; i < word.length(); i++) {
// 随机颜色
graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
// 旋转 -30 --- 30度
int jiaodu = random.nextInt(60) - 30;
// 换算弧度
double theta = jiaodu * Math.PI / 180;
// 获得字母数字
char c = word.charAt(i);
// 将c 输出到图片
graphics2d.rotate(theta, x, 20);
graphics2d.drawString(String.valueOf(c), x, 20);
graphics2d.rotate(-theta, x, 20);
x += 30;
}
// 将验证码内容保存session
request.getSession().setAttribute("checkcode_session", word);
// 步骤五 绘制干扰线
graphics.setColor(getRandColor(160, 200));
int x1;
int x2;
int y1;
int y2;
for (int i = 0; i < 30; i++) {
x1 = random.nextInt(width);
x2 = random.nextInt(12);
y1 = random.nextInt(height);
y2 = random.nextInt(12);
graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
}
// 将上面图片输出到浏览器 ImageIO
graphics.dispose();// 释放资源
//将图片写到response.getOutputStream()中
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* 取其某一范围的color
*
* @param fc
* int 范围参数1
* @param bc
* int 范围参数2
* @return Color
*/
private Color getRandColor(int fc, int bc) {
// 取其随机颜色
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}