Servlet中读取几种文件的方式
//获取全局上下文对象
ServletContext servletContext = this.getServletContext();
//用全局上下文对象获取真实路径。
String realPath = servletContext.getRealPath("/");
FileInputStream ain = new FileInputStream(realPath + "WEB-INF//classes//a.txt");//读取src下面的文件
FileInputStream bin = new FileInputStream(realPath + "b.txt");//读取web下的文件
FileInputStream cin = new FileInputStream(realPath + "WEB-INF//c.txt");//读取WEB-INF下的文件
响应对象和请求对象
HttpServletRequest request 请求对象
HttpServletResponse response 响应对象
请求对象和响应对象由服务器创建,管理和销毁,我们只需要使用。
原理:
- 当浏览器去请求服务器的资源时,服务器收到请求后,就会创建请求对象和响应对象。
- 请求对象就会封装请求的数据,服务器会把请求对象和响应对象,传递给service()方法发。
- 可以从请求对象中取出请求的数据来用。
- 要给浏览器响应数据时,可以把响应的数据放到响应对象中,当服务器真正响应浏览器时,就从响应对象中,取出数据响应给浏览器,
- 当响应完成之后,服务器就会销毁这次的请求对象和响应对象。
request和response对象都是由服务器创建,管理和销毁。
继承体系结构:
ServletRequest(接口)<--------继承<-------HttpServletRequest(接口)<--------实现 org.apache.catalina.connector.RequestFacade@6049a827
ServletResponse(接口)<---------继承— HttpServletResponse(接口)<-------------实现------org.apache.catalina.connector.ResponseFacade@3bec9d4
重定向:
- 两次请求两次响应。
- 地址栏发生变化,
- 不仅可以访问内部资源,也可以访问外部资源。
设置状态码 302 重定向
response.setStatus(302);
置响应头 location
response.setHeader(“location”,“http://127.0.0.1:8080/MyServlet/index.jsp”);
以上两步可以合成一个简便方法
response.sendRedirect(“http://www.baidu.com”);
设置响应头: 例如:content-type:text/html;charset=utf-8
setHeader(String headName,String headValue); 设置响应头的名称和值
setDateHeader(String name,long date); 设置日期头
setIntHeader(String name,int count); 设置数字头
设置响应体:响应体响应的是数据 得通过流的方式获取输出流写出数据
跳转外部资源。
response.setHeader("location","https://www.baidu.com");
跳转内部资源
response.setHeader("location", "/20201020___war_exploded/demo2");
重定向,不能重定向到WEB-INF下的资源
response.setHeader("location", "/20201020___war_exploded/WEB-INF/hehe.html");
PrintWriter getWriter();发送字符数据的对象
为了防止乱码,我们设置一下服务器对字符流的编码,默认服务器用的是ISO-8859-1
在获取流之前告诉服务器用的什么编码,
response.setCharacterEncoding("utf-8");
告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码
response.setHeader("content-type","text/html;charset=utf-8");
//以上两个方法可以合二为一
response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码
ServletOutputStream getOutputStream(); 发送字节数据的对象
获取字节流 用流向浏览器写出一张图片
ServletOutputStream sos = response.getOutputStream();
获取图片的真实路径
String realPath = this.getServletContext().getRealPath("/302.png");
获取输入流读取图片
FileInputStream fis = new FileInputStream(new File(realPath));
byte[] by = new byte[1024];
int len = 0;
while ((len = fis.read(by)) != -1) {
sos.write(by, 0, len);
}
生成验证码
//VertifyCode类
//获取2D画笔
Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
graphics.fillRect(0, 0, width, height);//填充背景
graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
//数字和字母的组合
String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
StringBuffer sBuffer = new StringBuffer();
int x = 10; //旋转原点的 x 坐标
String ch = "";
Random random = new Random();
for (int i = 0; i < 4; i++) {
graphics.setColor(getRandomColor());
//设置字体旋转角度
int degree = random.nextInt() % 30; //角度小于30度
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
sBuffer.append(ch);
//正向旋转
graphics.rotate(degree * Math.PI / 180, x, 45);
graphics.drawString(ch, x, 45);
//反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 45);
x += 48;
}
//画干扰线
for (int i = 0; i < 6; i++) {
// 设置随机颜色
graphics.setColor(getRandomColor());
// 随机画线
graphics.drawLine(random.nextInt(width), random.nextInt(height),
random.nextInt(width), random.nextInt(height));
}
//添加噪点
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2, 2);
}
return sBuffer.toString();
}
/**
* 随机取色
*/
private static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
return color;
}
//servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 200;
int height = 69;
//创建图片
BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//生成对应宽高的初始图片
String randomText = VerifyCode.drawRandomText(width, height, verifyImg);
//单独的一个类方法,出于代码复用考虑,进行了封装。
//功能是生成验证码字符并加上噪点,干扰线,返回值为验证码字符
request.getSession().setAttribute("verifyCode", randomText);
response.setContentType("image/png");//必须设置响应内容类型为图片,否则前台不识别
OutputStream os = response.getOutputStream(); //获取文件输出流
ImageIO.write(verifyImg, "png", os);//输出图片流
os.flush();
os.close();//关闭流
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
生成验证码用到的方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 40;
//创建图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//修饰图片
//设置图片背景色
Graphics g = image.getGraphics();//获取画笔
g.setColor(Color.PINK);//用画笔设置颜色
g.fillRect(0,0,width,height);//填充背景色
//画边框
g.setColor(Color.BLACK);
g.drawRect(0,0,width -1,height -1);
//写入验证码
/* g.setColor(Color.LIGHT_GRAY);
g.drawString("A",width/5*1,height/2);
g.drawString("w",width/5*2,height/2);
g.drawString("r",width/5*3,height/2);
g.drawString("t",width/5*4,height/2);*/
String msg = "fhswfcyuwafhHDYUAHJHjhuksadhf好烦粗的伤口恢复huekdhw";
Random random = new Random();
for (int i = 0; i < 4; i++) {
int index = random.nextInt(msg.length());
g.drawString(String.valueOf(msg.charAt(index)),width/5*i,height/2);
}
//画干扰线
g.setColor(Color.CYAN);
for (int i = 0; i < 5; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//将图片数据写入response输出流中
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
request对象
1.获取请求行 GET
request.getMethod();//获取请求方式
request.getContextPath();//获取项目名称
request.getRequestURI();//获取URI
request.getRequestURL();//获取URL
request.getRemoteAddr();//获取IP地址
request.getQueryString();//获取请求参数
request.getProtocol();//获取协议版本
2.获取请求头:
request.getHeader("user-agent");//获取请求头的值
request.getDateHeader(name);//获取日期头
request.getIntHeader(name)//获取数字头
3.获取请求体
请求体:专门用于封装Post请求的请求参数。
获取字符数据: getReader(); 返回一个高效的字符流 我们通过一次读取一行的 方法来获取请求参数数据 然后 拆分字符串获取我们想要的数据
4.通用的方式来获取请求参数
获取 请求参数
request.getParameter(name); 通过请求参数的名称来获取值
request.getParameterValues(“hobby”); 通过请求参数的名称,来获取值的数组 一般用于复选框
request.getParameterMap(); 获取所有参数的map集合
request.getParameterNames(); 获取所有参数的名称 枚举 不常用 了解
5.处理中文的乱码问题
处理get post 请求提交中文数据乱码问题
tomcat 8.0 以上 GET请求 中文参数 不乱码 tomcat已经处理了 我们不用处理
post 请求特有的方式 处理中文乱码
request.setCharacterEncoding("utf-8");
6:请求转发:
转发的特点:
- 一次请求一次响应
- 地址栏不发生变化
- 只能访问内部站点资源
request.getRequestDispatcher("/myservlet2").forward(request, response);
请求转发和重定向的区别:
重定向:
- 两次请求两次响应。
- 地址栏发生变化,
- 不仅可以访问内部资源,也可以访问外部资源。
请求转发:
- 一次请求一次响应
- 地址栏不发生变化
- 只能访问内部站点资源
域对象:在请求域的范围中共享数据
在一次请求的多个资源之间共享数据
request.setAttribute(“name”,“zhangsan”);
request.getAttribute(“name”);
request.removeAttribute(“name”);
什么时候使用重定向?什么时候使用请求转发?
- 如果需要在使用的多个资源中共享数据,则使用转发。
- 如一次性的数据存入请求域中,不要使用重定向来跳转资源,使用请求转发。
- 如果使用了重定向来跳转资源,还想要在多个资源间共享数据,那么这个数据存在请求域中,就共享不到了。