接着上篇(http://blog.csdn.net/q_sea__/article/details/79371154)继续写。
3、生成验证码
servlet代码:
package test.response;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/TestResponse")
public class TestResponse extends HttpServlet {
// 设置整个验证码的宽高
private static final int WIDTH = 130;
private static final int HEIGHT = 30;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1, 得到画图的对象
BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
//2, 绘制背景
drawBackGround(g);
//3, 绘制边框
drawBorder(g);
//4, 绘制干扰项
drawLine(g);
//5, 绘制字符
drawString((Graphics2D)g);
//6, 将图片输出
// 当把页面引入html时,为了防止网页读取缓存的图片。要设置响应头
// 设置3大主流浏览器不使用cache
response.setDateHeader("expires", -1);
response.setHeader("Cache-control", "no-cache");
response.setHeader("pragme", "no-cache");
ImageIO.write(bi, "jpg", response.getOutputStream());
}
// 为了达到旋转字符的目的,将参数类型变为 Graphics2D
private void drawString(Graphics2D g) {
String arr = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789";
g.setFont(new Font("微软雅黑", Font.BOLD, 25));
int x = 10;
for(int i = 0; i < 4; i++){
int y = 20 + new Random().nextInt(10);
// 设置画笔颜色
g.setColor(new Color(new Random().nextInt(255), new Random().nextInt(255),
new Random().nextInt(255)));
// 得到随机字符
String str = arr.charAt(new Random().nextInt(arr.length()))+"";
// 转换角度
int jd = (int) ((new Random().nextInt()%40)*Math.PI/180);
g.rotate(jd, x, y);
// 绘制干扰字符
g.drawString(str, x, y);
g.rotate(-jd, x, y);
x+=30;
}
}
private void drawLine(Graphics g) {
for(int i = 0; i < 4; i++){
// 生成随机颜色
g.setColor(new Color(new Random().nextInt(255), new Random().nextInt(255),
new Random().nextInt(255)));
// 生成随机点
int x1 = new Random().nextInt(WIDTH);
int y1 = new Random().nextInt(HEIGHT);
int x2 = new Random().nextInt(WIDTH);
int y2 = new Random().nextInt(HEIGHT);
// 绘制干扰线
g.drawLine(x1, y1, x2, y2);
}
}
private void drawBorder(Graphics g) {
// 设置边框颜色并绘制
g.setColor(Color.DARK_GRAY);
g.drawRect(1, 1, WIDTH-2, HEIGHT-2);
}
private void drawBackGround(Graphics g) {
// 设置背景颜色并填充
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
访问servlet:
4、实现跳转
servlet代码:
package test.response;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
import javax.print.attribute.ResolutionSyntax;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/TestResponse3")
public class TestResponse3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
*具体的执行过程查看下面的方法分析
*/
}
public void test2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* 一个实用的跳转技术
* 模拟当用户登录成功后,条到显示页面
* 使用meta+refresh实现
*/
String str = "<meta http-equiv='refresh' content='3;url=/javaWeb/1.jsp'>"+
"欢迎登录成功,3秒后跳转到首页。如果没有点击<a href=1.jsp>这里</a>";
// 因为涉及到中文,就要设计编码
response.setContentType("text/html;charset=UTF-8");
// 一般不会在servlet中输出数据,而是会转发(地址不变)给消息显示页面
// 转发给 message.jsp 页面
this.getServletContext().setAttribute("data", str);
RequestDispatcher r = this.getServletContext().getRequestDispatcher("/messag.jsp");
// messag.jsp页面就是将data数据输出,这里不在粘贴代码
r.forward(request, response);
}
public void test1(HttpServletResponse response) throws IOException {
// 简单的跳转
response.setHeader("refresh", "3;url=/javaWeb/TestResponse3");
// 生成一个随机数并打印
String str = new Random().nextInt(12205) + "";
response.getWriter().write(str);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
方法过程:
test1方法的功能是实现每3秒页面的刷新。
执行test2方法先看到的是:
当我们在访问这个servlet时,servlet会转发到messag.jsp页面中,所以我们看到的是jsp页面的显示。3秒后有跳转到1.jsp页面,因为是跳转所以地址栏会发生改变:
5、实现重定向
重定向和转发是有区别的,重定向的话,客户端会请求2次或多次,并且地址栏会发生改变。转发的话,客户端会请求一次,地址栏不会改变。
servlet代码:
package test.response;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestResponse5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置状态码,303表示重定向
response.setStatus(303);
// 设置响应信息
response.setHeader("location", "/javaWeb/1.jsp");
// 1.jsp就是一个简单的输出,这里不在粘贴代码
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
执行,因为是重定向所以地址栏会改变:
6、关于getWriter和getOutputStream的细节
这两个方法不能同时在一个servlet中使用,不然会出现错误。
servlet代码:
package test.response;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class TestResponse5
*
* 实现重定向
* 客户端两次请求服务器
*
* getOutputStream和getWriter方法不能一起使用
*
*/
@WebServlet("/TestResponse5")
public class TestResponse5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 不能一起使用,如果在一个方法后面,使用了转发,转到的页面也是不能使用与之互斥的方法
// 但是如果你使用了重定向,就不会有这个限制了。毕竟是两次访问嘛
response.getOutputStream().write("".getBytes());
response.getWriter().write("");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
执行后,服务器出现错误: