標籤:
這幾天一直在反覆學習的內容,Servlet,Filter,Session,MySQL,jsp。
今天以一個完整的小項目作為BS入門基礎的總結。
使用者在jsp頁面上輸入使用者名稱和密碼,經過filter進入servlet,與資料庫中的資料進行匹配,密碼和使用者名稱輸入正確則跳轉歡迎介面,否則返回登入頁面重新輸入。
項目ProjectOne_FirstTryBS 有:
src底下有:四個package(servlet,filter,model,util)和一個資料庫設定檔jdbc.properties。
WebContent底下有:jsp,META-INF,WEB-INF和web.xml。
具體索引
lib裡面有很多類庫,我壓縮成.rar放在資源上了。
我這裡用的是tomcat3.0,所以web.xml是不用自己配置的。
首先,我寫了三個jsp頁面:login.jsp ,error.jsp,welcome.jsp。login負責使用者輸入使用者名稱和密碼,是個登入頁面;error是使用者輸入錯誤時跳轉的一個中轉頁面;welcome是登陸成功的歡迎頁面。images檔案夾裡面有一張背景圖片bg.jpg。
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ page import="javax.servlet.http.*" %><%@ page import="com.yan.model.User"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>JSP登陸介面</title></head><body style="background:url('images/bg.jpg') no-repeat;"><div style="text-align:center; position:absolute; top:30%; left:45%" ><div style="width:100px; margin:0 auto;" ><form name="form" action="../../ProjectOne_FirstTryBS/checkservlet" method="post" ><h4>使用者名稱:</h4><input type="text" name="username" ><br><h4>密 碼:</h4><input type="password" name="passwd" ><br><br><input type="submit" name="submit" value="登入"><input type="reset" name="reset" value="重設"></form></div></div></body></html>form標籤下action指向你項目下的servlet檔案,因為servlet裡面有驗證資料庫中的使用者名稱和密碼,而filter是預設每一個請求之後都會進入的。在正常情況下,應該是通過filter進入servlet的。
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>中轉站介面</title></head><body style="background:url('images/bg.jpg') no-repeat;"><div style="text-align:center; position:absolute; top:30%; left:45%" ><div style="width:100px; margin:0 auto;" ><input type="submit" value="返回" onclick="window.location.href='login.jsp'" /></div></div></body></html>我的error.jsp上只有一個返回login.jsp的按鈕,目的就是能讓地址從servlet回到login.jsp
welcome.jsp
<%@page import="com.yan.model.User"%><%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>jsp歡迎介面</title></head><body style="background:url('images/bg.jpg') no-repeat;"><div style="text-align:center; position:absolute; top:30%; left:45%" ><div style="width:100px; margin:0 auto;" ><%User user = (User)session.getAttribute("user");%><div><h4>使用者的ID是:</h4><%=user.getId() %><br/><h4>你的Name是:</h4><%=user.getName() %><br/><h4>你的Password是:</h4><%=user.getPasswd() %><br/></div></div></div></body></html>在指令碼中,將user類放在session裡面,擷取使用者輸入的使用者名稱和密碼,以及資料庫中對應的ID。
web.xml也放上來吧,至此,WebContent的內容就結束了。
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ProjectOne_FirstTryBS</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
src裡面,我先把資料庫的配置說完,再說具體servlet和filter實現。因為資料庫的直接抄過去就行,不用理解。
jbdc.porpertise
#mysql DB properties#MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver#MYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDB //3306是我串連MySQL的連接埠號碼,你寫你的#MYSQL_DB_USERNAME=pankaj#MYSQL_DB_PASSWORD=pankaj123#Oracle DB PropertiesORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver#ORACLE_DB_URL=jdbc:oracle:thin:@192.168.100.36:1521:TFSORACLE_DB_URL=jdbc:oracle:thin:@10.50.9.63:1521:orclORACLE_DB_USERNAME=PBYL1030ORACLE_DB_PASSWORD=pbtestforhr2014#Oracle DB Properties 2ORACLE_DB_DRIVER_CLASS2=oracle.jdbc.driver.OracleDriverORACLE_DB_URL2=jdbc:oracle:thin:@192.168.100.36:1521:easdbtestORACLE_DB_USERNAME2=PBYL1030ORACLE_DB_PASSWORD2=pbyl20140418fortestmysqldriverclass=com.mysql.jdbc.Drivermysqljdbcurl=jdbc:mysql://主機IP地址:連接埠號碼/庫名mysqluser=rootmysqlpassword=你的登入MySQL的密碼
OracleConnection.java
package com.yan.util;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSource;import org.apache.commons.dbutils.QueryRunner;public class OracleConnection { private static DataSource dataSource; private static void initOracle() { Properties props = new Properties();InputStream in = null;//props.load(ToSaveErrlog.class.getClassLoader().getResourceAsStream("save2logdb.properties")); try {in = OracleConnection.class.getClassLoader() .getResourceAsStream("jdbc.properties"); props.load(in);} catch (FileNotFoundException e) {System.out.println("jdbc.properties not found");e.printStackTrace();} catch (IOException e) {System.out.println("read error in jdbc.properties ");e.printStackTrace();} BasicDataSource dbcpDataSource = new BasicDataSource(); dbcpDataSource.setUrl(props.getProperty("mysqljdbcurl")); dbcpDataSource.setDriverClassName(props.getProperty("mysqldriverclass")); dbcpDataSource.setUsername(props.getProperty("mysqluser")); dbcpDataSource.setPassword(props.getProperty("mysqlpassword")); dbcpDataSource.setDefaultAutoCommit(true); dbcpDataSource.setMaxActive(10); dbcpDataSource.setMaxIdle(5); dbcpDataSource.setMaxWait(500); OracleConnection.dataSource = (DataSource)dbcpDataSource; System.out.println("Initialize dbcp..."); } public static Connection getConnection() { try { if(OracleConnection.dataSource==null){ initOracle(); return OracleConnection.dataSource.getConnection(); }else { return OracleConnection.dataSource.getConnection(); }} catch (SQLException e) {e.printStackTrace();}return null; } public static QueryRunner getQueryRunner(){ if(OracleConnection.dataSource==null){ initOracle(); return new QueryRunner(OracleConnection.dataSource); }else { return new QueryRunner(OracleConnection.dataSource); } }}
User.java,裡面放的變數對應你資料庫裡面的欄位,比如說我資料庫中有三個欄位id,name,passwd;那麼User.java裡面的三個String也應該是id,name,passwd。
其中,name和passwd是使用者自訂的,而id是使用者不知道的,我在資料庫中對id的定義是(寫的不是正規文法,你們看得懂就行):
'id' (int(8), NOT NULL, AUTO INCREMENT, PRIMARY KEY)
下面是User.java
package com.yan.model;import java.io.Serializable;public class User implements Serializable {private static final long serialVersionUID = -1734127774270588940L;private String id;private String name;private String passwd;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPasswd() {return passwd;}public void setPasswd(String passwd) {this.passwd = passwd;}}
filter包裡面有兩個filter檔案,LogFilter.java和AuthorityFilter.java,Log是日誌過濾器,記錄請求從開始過濾到結束的過程;Authority是路徑過濾器,對各個訪問情況進行攔截或者允許存取。
LogFilter.java
package com.yan.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;//日誌過濾器,記錄登入過濾資訊,可以顯示在console,也可以錄入資料庫@WebFilter(filterName = "logfilter",urlPatterns = {"/*"})public class LogFilter implements Filter {private FilterConfig fConfig; public void init(FilterConfig fConfig) throws ServletException { this.fConfig = fConfig;} public void destroy() { this.fConfig = null;} //核心過濾部分 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /*---------下面代碼用於對使用者請求執行預先處理---------*/ //擷取ServletContext對象,用於記錄日誌 ServletContext context = this.fConfig.getServletContext(); long before = System.currentTimeMillis(); System.out.println("開始過濾..."); //將請求轉換成HttpServletRequest請求 HttpServletRequest hrequest = (HttpServletRequest)request; //記錄日誌 context.log("Filter已經截獲到使用者的請求地址: " + hrequest.getServletPath()); //Filter只是鏈式處理,請求依然允許存取到目的地址 chain.doFilter(request, response); /*---------下面代碼用於對伺服器響應執行後處理---------*/ long after = System.currentTimeMillis(); //記錄日誌 context.log("過濾結束"); //再次記錄日誌 context.log("請求被定位到" + hrequest.getRequestURI() + "所花的時間為: " + (after - before)); } public LogFilter() {}}
AuthorityFilter.java
package com.yan.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.annotation.WebInitParam;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;//登入過濾器,記錄使用者是否登入@WebFilter(filterName = "authorityfilter", urlPatterns = {"/*"}, initParams = {@WebInitParam(name = "encoding", value = "GBK"),@WebInitParam(name = "loginPage", value = "/jsp/login.jsp"),@WebInitParam(name = "checkservlet", value = "/checkservlet"),@WebInitParam(name = "proLogin", value = "/jsp/welcome.jsp")})public class AuthorityFilter implements Filter {private FilterConfig fConfig; public AuthorityFilter() {}public void destroy() {this.fConfig = null;}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//擷取該filter的配置參數String encoding = fConfig.getInitParameter("encoding");String loginPage = fConfig.getInitParameter("loginPage");String proLogin = fConfig.getInitParameter("proLogin");String checkservlet = fConfig.getInitParameter("checkservlet");//設定request編碼用的字元集request.setCharacterEncoding(encoding);HttpServletRequest requ = (HttpServletRequest)request;HttpSession session = requ.getSession(true);//擷取客戶請求頁面String requestPath = requ.getServletPath();//如果session範圍的user為null,即沒有登入//並且使用者請求的既不是登陸頁面,也不是處理登入的頁面/* 1.如果user為null,即從未登陸過,應該跳轉login頁面 * 2.如果使用者訪問的不是login頁面,應該跳轉login頁面 * 3.如果使用者沒有訪問過checkservlet,應該跳轉login頁面 * */if(session.getAttribute("user") == null && !requestPath.endsWith(loginPage)&& !requestPath.endsWith(checkservlet)) {//forward到登入頁面request.setAttribute("tip", "您還沒有登入");request.getRequestDispatcher(loginPage).forward(request, response);} else {//“允許存取”請求chain.doFilter(request, response);}}public void init(FilterConfig fConfig) throws ServletException {this.fConfig = fConfig;}}
CheckServlet.java 的流程主要是:從login.jsp提取參數,串連資料庫,判斷,跳轉
package com.yan.servlet;import java.io.IOException;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;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 javax.swing.JOptionPane;import org.apache.commons.dbutils.handlers.BeanListHandler;import com.mysql.jdbc.Connection;import com.mysql.jdbc.PreparedStatement;import com.yan.model.User;import com.yan.util.OracleConnection;import java.awt.*;import javax.swing.*;import java.util.regex.*;@WebServlet("/checkservlet")public class CheckServlet<AttenAudit> extends HttpServlet {private static final long serialVersionUID = 1L; public CheckServlet() { super(); } public void process (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("現在開始執行CheckServlet.java"); String u = request.getParameter("username"); String p = request.getParameter("passwd"); String sql = "select * from User where name = ? and passwd = ? " ; //u和p放在Object裡面傳給userList List<User> userList = new ArrayList<User>();try {userList = OracleConnection.getQueryRunner().query(sql, new BeanListHandler<User>(User.class),new Object[]{u,p});} catch (SQLException e) {e.printStackTrace();} //userList的內容不為空白代表輸入的使用者名稱和密碼的組合在資料庫中存在;為空白則表示使用者名稱或者密碼錯誤 if(userList.size()>0) { HttpSession session = request.getSession(true); session.setAttribute("user", userList.get(0)); //取userList裡面的第一組值Object[u,p] request.getRequestDispatcher("/jsp/welcome.jsp").forward(request, response); } else { JOptionPane.showMessageDialog(null, "使用者名稱或密碼錯誤,請重新輸入!", "哎呀呀", JOptionPane.WARNING_MESSAGE); //response.sendRedirect("../jsp/error.jsp"); request.getRequestDispatcher("/jsp/error.jsp").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {process(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {process(request, response);}}
接下來,開始測試。
首先你要啟動tomcat,然後在瀏覽器中輸入http://localhost:8080/ProjectOne_FirstTryBS/login.jsp,進入login.jsp
輸入錯誤的話,會有彈窗,然後console上也會有所反映。
跳轉到error.jsp,再回到login.jsp。輸入正確的話,
可以從通過以下語句傳參,再從welcome.jsp提取。
request.getRequestDispatcher("/jsp/welcome.jsp").forward(request, response);
以上,就是全過程。
【Servlet】串連MySQL實現驗證密碼登入(附帶詳細解析及lib附件)