(jsp三)簡單功能的實現:登入
簡單架構介紹:
C/S:客戶端/服務端
B(Browser)/S(Server):瀏覽器/伺服器(例:Tomcat)
Jsp檔案介紹:
jsp(Java Server Pages)—java服務端頁面,執行在伺服器端,是一個以.jsp為字尾的文字檔案
html、css—java客戶端頁面,執行在客戶端
在jsp檔案中可以出現的程式碼
html程式碼
jsp指令
page指令:
language:開發語言
contentType:伺服器返回的資料型別
charset:伺服器返回編碼格式
pageEncoding:當前頁面編碼格式
java程式碼
常見錯誤碼:
404:路徑錯誤,應該檢查檔案所在位置及路徑書寫是否正確
500:程式碼錯誤
a.前端程式碼
<body>
<%--
<!--方式一:通過java程式碼獲取繫結值,該方法已經過時,儘量不在
<!--java程式碼-->
<%
String str=(String)request.getAttribute("login_error");
%>
<form action="StudentServlet?flag=login" method="post">
使用者名稱:<input type="text" name="sname" /><br/>
密 ; 碼:<input type="password" name="spwd" /><br/>
<span style="color:red">
<!--jsp表示式,該表示式意為輸出該值-->
<%=str==null?"":str%>
</span>
<input type="submit" value="登入" />
</form>
--%>
<!--方式二:使用EL表示式通過繫結名獲取繫結值-->
<form action="StudentServlet?flag=login" method="post">
使用者名稱:<input type="text" name="sname" /><br/>
密 碼:<input type="password" name="spwd" /><br/>
<span style="color:red">${login_error}</span>
<input type="submit" value="登入" />
</form>
</body>
注1:通常情況下一張表的所有操作都由一個Servlet完成,如何實現?可以通過在表單提交資料時附帶一個引數,這個引數就是代表該表單提交的資料所要進行的操作,然後由服務端獲取該引數,再通過條件語句執行對應的邏輯,所以需要對之前的doGet方法以及註冊頁面進行一些改動,在註冊頁面中也新增相應的flag值為regist,使得同一個servlet中的同一個方法可以完成對一個表的多個操作,給表單附帶引數方法為Servlet?flag=?,如login.jsp頁面程式碼中的action值所示。
注2:EL表示式(Excepression Language):表示式語言,結構是${},可用來替代jsp中的java表示式
b.StudentServlet程式碼
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//由於瀏覽器端設定編碼集為UTF-8,而伺服器端未設定編碼集,所以伺服器端會預設使用ISO-8859-1編碼集進行解碼,就會出現亂碼,故需要在伺服器端也設定編碼集為UTF-8
request.setCharacterEncoding("UTF-8");
//先獲取flag的值
String flag=request.getParameter("flag");
//獲取student的操作介面物件
IStudentDAO dao=new StudentDAOImpl();
//註冊
if("regist".equals(flag)){
//拿到表單傳送的資料
//getParameter()方法為獲取對應表單值,返回值為字串型別
//根據表單中的引數名獲取引數值,如果引數名與表單中所寫表單名不一致,則服務端接受到的表單值為null
String sname=request.getParameter("sname");
String spwd=request.getParameter("spwd");
//因為拿到的為字串型別,而student類中age為int型別,故需要型別轉換
int sage=Integer.parseInt(request.getParameter("sage"));
String ssex=request.getParameter("ssex");
//將資料存入到資料庫
//將資料封裝為Student物件
Student stu=new Student(sname,spwd,sage,ssex);
//呼叫dao的儲存方法,將stu物件儲存到資料庫
dao.saveStudent(stu);
//註冊成功以後重新訪問login.jsp檔案
//通過重定向方法,使得註冊成功後伺服器能夠返回登入頁面
response.sendRedirect("login.jsp");
}
//登入
if("login".equals(flag)){
String sname=request.getParameter("sname");
String spwd=request.getParameter("spwd");
Student stu=dao.findStudentBySnameAndSpwd(sname, spwd);
if(stu==null){
//查無此人,則進行提示並返回登入頁面
//設值繫結,將某繫結值繫結至request並給其一個繫結名,則重定向檔案可通過該繫結名獲取該繫結值
//第一個引數為繫結名,第二個引數為繫結值
request.setAttribute("login_error","查無此人");
//請求轉發
request.getRequestDispatcher("login.jsp").forward(request, response);
}else{
//顯示
}
}
}
注:重定向為一次請求一次響應一次請求一次響應,在使用者登入失敗時應該再次返回登入頁面並進行提示,所以應該在servlet方判斷後向login傳送登入失敗資訊,如何傳送資訊?可以通過request.setAttribute(arg0,arg0)方法,第一個引數繫結名與第二個引數繫結值來傳送資訊至jsp端,但是由於重定向時第二次請求時第一次繫結的資料會被清空,所以就回導致並未將提示資訊傳送至jsp端,如何解決?不使用重定向,而使用請求轉發request.getRequestDispatcher().forward(request,response)方法,第一個方法為獲取請求,引數為所要請求的頁面,第二個方法為轉發,轉發方法有兩個引數,第一個為請求,第二個為響應,如果查無此人,則進行提示並返回登入頁面
程式碼實現效果:
c.Student類中增加一個帶sid的構造方法
d.IStudentDAO程式碼
public interface IStudentDAO {
public void saveStudent(Student stu);
//通過使用者名稱及密碼只能查到一個學生物件,所以使用者名稱不允許重複,但在本例中不進行實現
public Student findStudentBySnameAndSpwd(String sname,String spwd);
}
e.StudentImpl新增程式碼
public Student findStudentBySnameAndSpwd(String sname, String spwd) {
Student stu=null;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement("SELECT sid,sname,spwd,sage,ssex FROM student WHERE sname=? AND spwd=?");
ps.setString(1,sname);
ps.setString(2,spwd);
rs=ps.executeQuery();
if(rs.next()){
stu=new Student(rs.getInt("sid"),sname,spwd,rs.getInt("sage"),rs.getString("ssex"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil.closeConnection(rs, ps, conn);
}
return stu;
}