完整的驗證及訊息提示
阿新 • • 發佈:2018-11-01
首先我們要先建立一個生成圖片的類,並且儲存使用者所需要輸入的驗證碼字串,其次就是把生成的圖片放到網頁中。
看目錄結構
先了解如何生成圖片VerfiCode.java
package Dao;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* Created by online on 15-9-17.
*/
public class VerfiCode {
//這是一個畫筆類,進行驗證碼的描繪,並返回一個供使用者驗證的字串
private int w = 70;
private int h = 35;
private Random r = new Random();
// {"宋體", "華文楷體", "黑體", "華文新魏", "華文隸書", "微軟雅黑", "楷體_GB2312"}
private String[] fontNames = {"宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312"};
// 可選字元
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
// 背景色
private Color bgColor = new Color(255, 255, 255);
// 驗證碼上的文字
private String text ;
// 生成隨機的顏色
private Color randomColor () {
int red = r.nextInt(150);//在0-149之內生成隨機數
int green = r.nextInt(150 );
int blue = r.nextInt(150);
return new Color(red, green, blue);//生成顏色,供生成字型時使用
}
// 生成隨機的字型
private Font randomFont () {
int index = r.nextInt(fontNames.length);
String fontName = fontNames[index];//生成隨機的字型名稱
int style = r.nextInt(4);//生成隨機的樣式, 0(無樣式), 1(粗體), 2(斜體), 3(粗體+斜體)
int size = r.nextInt(5) + 24; //生成隨機字號, 24 ~ 28
return new Font(fontName, style, size);//生成字型樣式,供生成字型時使用
}
// 畫干擾線
private void drawLine (BufferedImage image) {
int num = 3;//一共畫3條
Graphics2D g2 = (Graphics2D)image.getGraphics();
for(int i = 0; i < num; i++) {//生成兩個點的座標,即4個值(x1,y1),(x2,y2)
int x1 = r.nextInt(w);
int y1 = r.nextInt(h);
int x2 = r.nextInt(w);
int y2 = r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));
g2.setColor(Color.BLUE); //干擾線是藍色
g2.drawLine(x1, y1, x2, y2);//畫線
}
}
// 隨機生成一個字元
private char randomChar () {
int index = r.nextInt(codes.length());
return codes.charAt(index);//生成這個要輸入的字型,供生成字型使用
}
// 建立BufferedImage
private BufferedImage createImage () {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D)image.getGraphics();
g2.setColor(this.bgColor);//背景顏色,白色
g2.fillRect(0, 0, w, h);
return image;
}
// 呼叫這個方法得到驗證碼
public BufferedImage getImage () {
BufferedImage image = createImage();//建立圖片緩衝區
Graphics2D g2 = (Graphics2D)image.getGraphics();//得到繪製環境
StringBuilder sb = new StringBuilder();//用來裝載生成的驗證碼文字
// 向圖片中畫4個字元
for(int i = 0; i < 4; i++) {//迴圈四次,每次生成一個字元
String s = randomChar() + "";//隨機生成一個字母
sb.append(s); //把字母新增到sb中,最後得到一個字串,供驗證使用
float x = i * 1.0F * w / 4; //設定當前字元的x軸座標
g2.setFont(randomFont()); //設定隨機字型,這個是上面的方法得到的字樣
g2.setColor(randomColor()); //設定隨機顏色,這個是上面的方法得到的顏色
g2.drawString(s, x, h-5); //畫圖
}
this.text = sb.toString(); //把生成的字串賦給了this.text
drawLine(image); //新增干擾線
return image;
}
// 返回驗證碼圖片上的文字
public String getText () {
return text;
}
// 儲存圖片到指定的輸出流,就是把圖片放到哪。這個專案就是把得到的圖片流放到頁面中顯示
public static void output (BufferedImage image, OutputStream out)
throws IOException {
ImageIO.write(image, "JPEG", out);
}
}
- 其次瞭解生成的圖片是如何放到頁面中的Verfi.java
package action;
import Dao.VerfiCode;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* Created by online on 15-9-17.
*/
@WebServlet(urlPatterns = "/verfi",name = "ver")
public class Verfi extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 使用驗證碼 防止暴力登入。無限訪問 導致伺服器癱瘓
*/
VerfiCode ver = new VerfiCode();
BufferedImage bi = ver.getImage();//得到驗證碼這張圖片
req.getSession().setAttribute("verfi",ver.getText());//session儲存字串供驗證,只有使用者輸入的驗證碼和這個匹配才能成功登入。
VerfiCode.output(bi,resp.getOutputStream());//寫入到頁面中
}
}
- 由於登入和註冊的驗證碼要分別進行驗證不同步,所以有Verfi1.java
package action;
import Dao.VerfiCode;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* Created by online on 15-9-17.
*/
@WebServlet(urlPatterns = "/verfi1",name = "ver1")
public class Verfi1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 使用驗證碼 防止暴力登入。無限訪問 導致伺服器癱瘓
*/
VerfiCode ver = new VerfiCode();
BufferedImage bi = ver.getImage();//得到驗證碼這張圖片
req.getSession().setAttribute("verfi1",ver.getText());//session儲存字串供驗證,只有使用者輸入的驗證碼和這個匹配才能成功登入。
VerfiCode.output(bi,resp.getOutputStream());//寫入到頁面中
}
}
- 寫入到頁面中 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主介面</title>
<%--新加入的程式碼--%>
<script>
function _change(){
/*
1.得到img元素
2.修改其src為/verfi
*/
var imgEle=document.getElementById("img");
imgEle.src ="/verfi?a="+new Date().getTime();//保證圖片不重名,所以加上時間命名
}
function _change1(){
/*
1.得到img元素
2.修改其src為/verfi
*/
var imgEle=document.getElementById("img1");
imgEle.src ="/verfi?a="+new Date().getTime();//保證圖片不重名,所以加上時間命名
}
</script>
<%--新加入的程式碼--%>
</head>
<body>
<form name="regist" action="/regist" method="post">
使用者名稱:<input type="text" name="username"/>
密碼:<input type="password" name="password"/>
驗證碼:<input type="text" name="ver"/>
<input type="submit" value="註冊"/>
</form>
<img id="img" src="/verfi" alt="驗證碼"/>
<a href="javascript:_change()">換一張</a>
<form name="login" action="/login" method="post">
使用者名稱:<input type="text" name="username" />
密碼:<input type="password" name="password" />
驗證碼:<input type="text" name="ver1"/>
<input type="submit" value="登入"/>
</form>
<img id="img1" src="/verfi1" alt="驗證碼"/>
<a href="javascript:_change1()">換一張</a>
<%--js指令碼,每一次點選這個連結,即進行該圖片的重新整理--%>
</body>
</html>
- 驗證碼圖片和輸入驗證碼的文字框都有了,而我們要得是圖片上的內容和輸入的內容一致時才允許登入或註冊。所以我們要在Servlet中獲取使用者輸入的資訊並和生成圖片時儲存的文字進行對比。
- 首先看登入的servlet,由於程式碼只是部分修改,所以我把修改的部分用註釋‘這’進行標註 Homework.java
package action;
import Dao.AddandSelect;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
/**
* Created by online on 15-9-11.
*/
@WebServlet(urlPatterns = "/login" ,name = "stuLogin")
public class Homework extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//System.out.println(req.getParameter("username"));//req.getParameter();這個方法就是獲取jsp頁面form表單傳送過來的資料。
//System.out.println(req.getParameter("password"));//這裡執行並在頁面輸入後提交 則會在控制檯看到輸入內容。
req.setCharacterEncoding("utf-8");//這
HttpSession session = req.getSession();//建立session物件
String username= (String) req.getParameter("username");
String password= (String) req.getParameter("password");
String verfi1= (String) req.getParameter("ver1");//這
session.setAttribute("username",username);//這
try {
if (AddandSelect.valiuandp(username,password)){//驗證是否匹配到資訊匹配到就進入到success.jsp,不匹配就返回登入介面。
if (verfi1.equalsIgnoreCase((String) req.getSession().getAttribute("verfi1"))){//這,驗證驗證碼是否正確
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}else {
req.setAttribute("cuo","驗證碼錯誤");//設定錯誤提示資訊,在index.jsp加入java程式碼,若req.getParameter("cuo")不為空,即顯示在頁面中。
req.getRequestDispatcher("/index.jsp").forward(req,resp);//跳轉到登入頁面
}//到這
}else {
req.setAttribute("cuo","使用者名稱或密碼錯誤");
req.getRequestDispatcher("/index.jsp").forward(req,resp);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
- 同理Regist.java,由於註冊沒有頁面的跳轉,無論對與錯都是返回到index.jsp,所以只要加入兩個程式碼塊就行。
String verfi= (String) req.getParameter("ver");
if (!verfi.equalsIgnoreCase((String)req.getSession()
.getAttribute("verfi")))
req.setAttribute("cuo","驗證碼錯誤");
至於加到何處,看需求,自行加入。
到這裡算是加入了大部分驗證,但是還需要有非空輸入驗證和註冊不允許重使用者名稱驗證。
其實說到底,javaee的起步是jsp頁面->servlet->業務邏輯類的處理->servlet->jsp。 在這個簡單的專案中就是index.jsp->Homework.java->AddandSelect.java->Homework.java->index.jsp。
其餘的功能等等都是一些換湯不換藥的問題
由於javaee想要做更快捷和更輕量(功能多程式碼少速度快)的專案還是需要學會使用框架
這個專案我只做了登入和註冊,後面等功能所運用的知識也大致一樣
專案原始碼https://github.com/pckonline/homework_jsp思路可以參考該原始碼