開發模式的介紹
在Web開發模式中,有兩個主要的開發結構,稱爲模式一(Mode I)和模式二(Mode II).
首先我們來理清一些概念吧:
- DAO(Data Access Object):主要對數據的操作,增加、修改、刪除等原子性操作。
- Web層:界面+控制器,也就是說JSP【界面】+Servlet【控制器】
- Service業務層:將多個原子性的DAO操作進行組合,組合成一個完整的業務邏輯
- 控制層:主要使用Servlet進行控制
- 數據訪問層:使用DAO、Hibernate、JDBC技術實現對數據的增刪改查
- JavaBean用於封裝數據,處理部分核心邏輯,每一層中都用到!
模式一
模式一指的就是在開發中將顯示層、控制層、數據層的操作統一交給JSP或者JavaBean來進行處理!
模式一有兩種情況:
- 完全使用JSP做開發
- 優點:
- 開發速度賊快,只要寫JSP就行了,JavaBean和Servlet都不用設計!
- 小幅度修改代碼方便,直接修改JSP頁面交給WEB容器就行了,不像Servlet還要編譯成.class文件再交給服務器!【當然了,在ide下開發這個也不算是事】
- 缺點:
- 程序的可讀性差、複用性低、代碼複雜!什麼jsp代碼、html代碼都往上面寫,這肯定很難閱讀,很難重用!
- 使用JSP+JavaBean做開發
- 優點:
- 程序的可讀性較高,大部分的代碼都寫在JavaBean上,不會和HTML代碼混合在一起,可讀性還行的。
- 可重複利用高,核心的代碼都由JavaBean開發了,JavaBean的設計就是用來重用、封裝,大大減少編寫重複代碼的工作!
- 缺點:
- 沒有流程控制,程序中的JSP頁面都需要檢查請求的參數是否正確,異常發生時的處理。顯示操作和業務邏輯代碼工作會緊密耦合在一起的!日後維護會困難
應用例子:
我們使用JavaBean+JSP開發一個簡易的計算器吧,效果如圖下:
- 首先開發JavaBean對象
public class Calculator {
private double firstNum;
private double secondNum;
private char Operator = '+';
private double result;
//JavaBean提供了計算的功能
public void calculate() {
switch (this.Operator) {
case '+':
this.result = this.firstNum + this.secondNum;
break;
case '-':
this.result = this.firstNum - this.secondNum;
break;
case '*':
this.result = this.firstNum * this.secondNum;
break;
case '/':
if (this.secondNum == 0) {
throw new RuntimeException("除數不能爲0");
}
this.result = this.firstNum / this.secondNum;
break;
default:
throw new RuntimeException("傳入的字符非法!");
}
}
public double getFirstNum() {
return firstNum;
}
public void setFirstNum(double firstNum) {
this.firstNum = firstNum;
}
public double getSecondNum() {
return secondNum;
}
public void setSecondNum(double secondNum) {
this.secondNum = secondNum;
}
public char getOperator() {
return Operator;
}
public void setOperator(char operator) {
Operator = operator;
}
public double getResult() {
return result;
}
public void setResult(double result) {
this.result = result;
}
}
- 再開發顯示頁面
<%--開發用戶界面--%>
<form action="/zhongfucheng/1.jsp" method="post">
<table border="1">
<tr>
<td colspan="2">簡單計數器</td>
<td></td>
</tr>
<tr>
<td>第一個參數:</td>
<td><input type="text" name="firstNum"></td>
</tr>
<tr>
<td>運算符</td>
<td>
<select name="operator">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
</td>
</tr>
<tr>
<td>第二個參數:</td>
<td><input type="text " name="secondNum"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交"></td>
<td></td>
</tr>
</table>
</form>
- 效果:
- 獲取得到顯示頁面提交的參數,調用JavaBean的方法,最後輸出結果!
<%--獲取得到Bean對象--%>
<jsp:useBean id="calculator" class="domain.Calculator" scope="page"/>
<%--設置Bean對象的數據--%>
<jsp:setProperty name="calculator" property="*"/>
<%--調用Caculator的方法計算出值--%>
<jsp:scriptlet>
calculator.calculate();
</jsp:scriptlet>
<%--得出的結果:--%>
<c:out value="計算得出的結果是:"/>
<jsp:getProperty name="calculator" property="firstNum"/>
<jsp:getProperty name="calculator" property="operator"/>
<jsp:getProperty name="calculator" property="secondNum"/>
<c:out value="="/>
<jsp:getProperty name="calculator" property="result"/>
- 效果:
開發這個簡易的計算器,只用了一個JSP頁面和一個JavaBean完成!
總的來說,Mode I 適合小型的開發,複雜程序低的開發,因爲Mode I 的特點就是開發速度快,但在進行維護的時候就要付出更大的代價!
模式二
Mode II 中所有的開發都是以Servlet爲主體展開的,由Servlet接收所有的客戶端請求,然後根據請求調用相對應的JavaBean,並所有的顯示結果交給JSP完成!,也就是俗稱的MVC設計模式!
MVC設計模式:
- 顯示層(View):主要負責接受Servlet傳遞的內容,調用JavaBean,將內容顯示給用戶
- 控制層(Controller):主要負責所有用戶的請求參數,判斷請求參數是否合法,根據請求的類型調用JavaBean,將最終的處理結果交給顯示層顯示!
- 模型層(Mode):模型層包括了業務層,DAO層。
應用例子:
我們使用MVC模式開發一個簡單的用戶登陸註冊的案例吧!作爲一個簡單的用戶登陸註冊,這裏就直接使用XML文檔當作小型數據庫吧!
①搭建開發環境
- 導入相對應的開發包
- 創建程序的包名
- 創建xml文件,當做小型的數據庫
②開發實體User
private int id;
private String username;
private String password;
private String email;
private Date birthday;
//....各種setter、getter
③開發dao
-
這個根據業務來開發,我們是登陸註冊,那應該提供什麼功能呢?註冊(外界傳遞一個User對象進來,我可以在XML文檔多一條信息)。登陸(外界傳遞用戶名和密碼過來,我就在XML文檔中查找有沒該用戶名和密碼,如果有就返回一個User對象)
-
3.1登陸功能:
//外界傳遞用戶名和密碼進來,我要在XML文檔中查找是否有該條記錄
public User find(String username, String password) {
//得到XML文檔的流對象
InputStream inputStream = UserImplXML.class.getClassLoader().getResourceAsStream("user.xml");
//得到dom4j的解析器對象
SAXReader saxReader = new SAXReader();
try {
//解析XML文檔
Document document = saxReader.read(path);
//使用XPATH技術,查找XML文檔中是否有傳遞進來的username和password
Element element = (Element) document.selectSingleNode("//user[@username='" + username + "' and@password='" + password + "']");
if (element == null) {
return null;
}
//如果有,就把XML查出來的節點信息封裝到User對象,返回出去
User user = new User();
user.setId(Integer.parseInt(element.attributeValue("id")));
user.setUsername(element.attributeValue("username"));
user.setPassword(element.attributeValue("password"));
user.setEmail(element.attributeValue("email"));
//生日就需要轉換一下了,XML文檔保存的是字符串,User對象需要的是Date類型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
Date birthday = simpleDateFormat.parse(element.attributeValue("birthday"));
user.setBirthday(birthday);
//返回User對象出去
return user;
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("初始化時候出錯啦!");
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("查詢的時候出錯啦!");
}
}
- 做完一個功能,最好就測試一下,看有沒有錯誤再繼續往下寫!
private String username = "zhongfucheng";
private String password = "123";
@Test
public void testLogin() {
UserImplXML userImplXML = new UserImplXML();
User user = userImplXML.find(username, password);
System.out.println(user.getBirthday());
System.out.println(user.getEmail());
System.out.println(user.getId());
System.out.println(user.getUsername());
System.out.println(user.getPassword());
}
- 效果:
3.2註冊功能
//註冊功能,外界傳遞一個User對象進來。我就在XML文檔中添加一條信息
public void register(User user) {
//獲取XML文檔路徑!
String path = UserImplXML.class.getClassLoader().getResource("user.xml").getPath();
try {
//獲取dom4j的解析器,解析XML文檔
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(path);
//在XML文檔中創建新的節點
Element newElement = DocumentHelper.createElement("user");
newElement.addAttribute("id", String.valueOf(user.getId()));
newElement.addAttribute("username", user.getUsername());
newElement.addAttribute("email", user.getEmail());
newElement.addAttribute("password", user.getPassword());
//日期返回的是指定格式的日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
String date = simpleDateFormat.format(user.getBirthday());
newElement.addAttribute("birthday",date);
//把新創建的節點增加到父節點上
document.getRootElement().add(newElement);
//把XML內容中文檔的內容寫到硬盤文件上
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
outputFormat.setEncoding("UTF-8");
XMLWriter xmlWriter = new XMLWriter(new FileWriter(path),outputFormat);
xmlWriter.write(document);
xmlWriter.close();
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException("註冊的時候出錯了!!!");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("註冊的時候出錯了!!!");
}
}
- 我們也測試一下有沒有錯誤!
@Test
public void testRegister() {
UserImplXML userImplXML = new UserImplXML();
//這裏我爲了測試的方便,就添加一個帶5個參數的構造函數了!
User user = new User(10, "nihao", "123", "[email protected]", new Date());
userImplXML.register(user);
}
- 注意!測試的結果是在classes目錄下的user.xml文件查詢的!因爲我們是用Test來測試代碼,讀取XML文件時使用的是類裝載器的方法,在編譯後,按照WEB的結構目錄,XML文件的讀寫是在WEB-INF的classes目錄下的!
- DAO的實現已經開發完成了,接下來我們就對DAO的實現進行抽取。【當然了,也可以先寫DAO再寫DAO的實現】
④開發service層
service層的開發就非常簡單了!上面已經說了,service層就是:將多個原子性的DAO操作進行組合,組合成一個完整的業務邏輯。簡單來說:對web層提供所有的業務服務的!
在邏輯代碼不是非常複雜的情況下,我們可以沒有service層的,這裏還是演示一下吧!
public class UserServiceXML {
//Service層就是調用Dao層的方法,我們就直接在類中創建Dao層的對象了
UserDao userImplXML = new UserImplXML();
public void register(User user) {
userImplXML.register(user);
}
public void login(String username, String password) {
userImplXML.find(username, password);
}
}
- 當然了,爲了更好的解耦,也把它抽取成接口!
⑤開發web層
5.1我們來先做註冊的界面吧!
- 提供註冊界面的Servlet
public class RegisterUIServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//直接跳轉到顯示註冊界面的JSP
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
this.doPost(request, response);
}
}
- 開發註冊界面的JSP
<h1>歡迎來到註冊界面!</h1>
<%--提交給處理註冊的處理Servlet--%>
<form method="post" action="${pageContext.request.contextPath}/RegisterServlet">
<table>
<%--對於id來講,是服務器分配的!不需要用戶自己輸入--%>
<tr>
<td>用戶名</td>
<td>
<input type="text " name="username">
</td>
</tr>
<tr>
<td>密碼</td>
<td>
<input type="text" name="password">
</td>
</tr>
<tr>
<td>確認密碼</td>
<td>
<input type="text" name="password">
</td>
</tr>
<tr>
<td>郵箱</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text " name="birethday">
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交">
</td>
<td>
<input type="reset" value="重置!">
</td>
</tr>
</table>
</form>
- JSP頁面是這樣子的
- 接下來,我們要開發處理用戶註冊提交的Servlet
//首先要接受Parameter的參數,封裝到User裏面去
String username = request.getParameter("username");
String password = request.getParameter("password");
//......如果參數過多,我們就要寫好多好多類似的代碼了...
- 此時,我們應該想起反射機制中的BeanUtils開發包..爲了更好地重用,我就將它寫成一個工具類!
/*
* 將Parameter參數的數據封裝到Bean中,爲了外邊不用強轉,這裏就使用泛型了!
*
* @request 由於要獲取的是Parameter參數的信息,所以需要有request對象
* @tClass 本身是不知道封裝什麼對象的,所以用class
*
* */
public static <T> T request2Bean(HttpServletRequest httpServletRequest, Class<T> tClass) {
try {
//創建tClass的對象
T bean = tClass.newInstance();
//獲取得到Parameter中全部的參數的名字
Enumeration enumeration = httpServletRequest.getParameterNames();
//遍歷上邊獲取得到的集合
while (enumeration.hasMoreElements()) {
//獲取得到每一個帶過來參數的名字
String name = (String) enumeration.nextElement();
//獲取得到值
String value = httpServletRequest.getParameter(name);
//把數據封裝到Bean對象中
BeanUtils.setProperty(bean, name, value);
}
return bean;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("封裝數據到Bean對象中出錯了!");
}
}
- 經過我們測試,日期不能直接封裝到Bean對象中,會直接報出異常!
-
對於日期而言,需要一個日期轉換器。當BeanUtils的setProperty()方法檢測到日期時,會自動調用日期轉換器對日期進行轉換,從而實現封裝!
-
於是乎,就在上面的方法中添加以下一句代碼
//日期轉換器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
- 還有一個問題,用戶的id不是自己輸入的,是由程序生成的。我們避免id的重複,就使用UUID生成用戶的id吧!爲了更好的重用,我們也把它封裝成一個方法!
/*生成ID*/
public static int makeId() {
return Integer.parseInt(UUID.randomUUID().toString());
}
- 好的,我們來測試一下吧!以下是RegisterServlet的代碼
User user = WebUtils.request2Bean(request, User.class);
user.setId(WebUtils.makeId());
//調用service層的註冊方法,實現註冊
ServiceBussiness serviceBussiness = new UserServiceXML();
serviceBussiness.register(user);
- 效果:
上面的代碼是不夠完善的(沒有校驗用戶輸入的信息、註冊成功或失敗都沒有給出提示..等等)
-
下面,我們來校驗用戶輸入的信息吧,如果用戶輸入的信息不合法,就直接跳轉回註冊的界面。
-
剛纔我們是用BeanUtils把Parameter的信息全部直接封裝到User對象中,但現在我想要驗證用戶提交表單的數據,也應該把表單的數據用一個對象保存着【面向對象的思想、封裝、重用】
-
流程是這樣子的:當用戶提交表單數據的時候,就把表單數據封裝到我們設計的表單對象上,調用表單對象的方法,驗證數據是否合法!
-
好了,我們來開發一個表單的對象吧,最重要的是怎麼填寫validate()方法!!
public class FormBean {
//表單提交過來的數據全都是String類型的,birthday也不例外!
private String username;
private String password;
private String password2;
private String email;
private String birthday;
/*用於判斷表單提交過來的數據是否合法*/
public boolean validate() {
return false;
}
//......各種setter、getter方法
}
- 以下是我定下的規則:
- 方法的代碼如下:
public boolean validate() {
//用戶名不能爲空,並且要是3-8的字符 abcdABcd
if (this.username == null || this.username.trim().equals("")) {
return false;
} else {
if (!this.username.matches("[a-zA-Z]{3,8}")) {
return false;
}
}
//密碼不能爲空,並且要是3-8的數字
if (this.password == null || this.password.trim().equals("")) {
return false;
} else {
if (!this.password.matches("\\d{3,8}")) {
return false;
}
}
//兩次密碼要一致
if (this.password2 != null && !this.password2.trim().equals("")) {
if (!this.password2.equals(this.password)) {
return false;
}
}
//郵箱可以爲空,如果爲空就必須合法
if (this.email != null && !this.email.trim().equals("")) {
if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {
System.out.println("郵箱錯誤了!");
return false;
}
}
//日期可以爲空,如果爲空就必須合法
if (this.birthday != null && !this.birthday.trim().equals("")) {
try {
DateLocaleConverter dateLocaleConverter = new DateLocaleConverter();
dateLocaleConverter.convert(this.birthday);
} catch (Exception e) {
System.out.println("日期錯誤了!");
return false;
}
}
//如果上面都沒有執行,那麼就是合法的了,返回true
return true;
}
- 處理表單數據的Servlet,代碼是這樣子的:
//將表單的數據封裝到formBean中
FormBean formBean = WebUtils.request2Bean(request, FormBean.class);
//驗證表單的數據是否合法,如果不合法就跳轉回去註冊的頁面
if(formBean.validate()==false){
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
return;
}
try {
//將表單的數據封裝到User對象中
User user = WebUtils.request2Bean(request, User.class);
user.setId(WebUtils.makeId());
//調用service層的註冊方法,實現註冊
ServiceBussiness serviceBussiness = new UserServiceXML();
serviceBussiness.register(user);
} catch (Exception e) {
e.printStackTrace();
}
- 接下來我們測試一下吧!將所有的信息都按照規定的輸入!
- 沒有問題!已經將記錄寫到XML文件上了!
- 但是,如果我沒有輸入日期呢?
它拋出了錯誤!原因也非常簡單:表單數據提交給Servlet,Servlet將表單的數據(Parameter中的數據)用BeanUtils封裝到User對象中,當封裝到日期的時候,發現日期爲null,無法轉換成日期對象!
那我們現在要怎麼解決呢?
首先我們要明確:因爲我們在設定的時候,已經允許了email和birthday可以爲空,那麼在DAO層就應該有相應的邏輯判斷email和birthday是否爲空!
if (user.getEmail() == null) {
newElement.addAttribute("email", "");
} else {
newElement.addAttribute("email", user.getEmail());
}
//如果不是空才格式化信息
if (user.getBirthday() != null) {
//日期返回的是指定格式的日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = simpleDateFormat.format(user.getBirthday());
newElement.addAttribute("birthday", date);
} else {
newElement.addAttribute("birthday", "");
}
解決辦法:
- Parameter中的數據如果是"",我就不把數據封裝到User對象中,執行下一次循環!
public static <T> T request2Bean(HttpServletRequest httpServletRequest, Class<T> tClass) {
try {
//創建tClass的對象
T bean = tClass.newInstance();
//獲取得到Parameter中全部的參數的名字
Enumeration enumeration = httpServletRequest.getParameterNames();
//日期轉換器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
//遍歷上邊獲取得到的集合
while (enumeration.hasMoreElements()) {
//獲取得到每一個帶過來參數的名字
String name = (String) enumeration.nextElement();
//獲取得到值
String value = httpServletRequest.getParameter(name);
//如果Parameter中的數據爲"",那麼我就不封裝到User對象裏邊去!執行下一次循環
if (value == "") {
continue;
} else {
//把數據封裝到Bean對象中
BeanUtils.setProperty(bean, name, value);
}
}
return bean;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("封裝數據到Bean對象中出錯了!");
}
}
- 效果:
將數據封裝到User對象中還有另外一個辦法:
- 我們知道BeanUtils有個copyProperties()方法,可以將某個對象的成員數據拷貝到另外一個對象的成員變量數據上(前提是成員變量的名稱相同!)我們FormBean對象的成員變量名稱和User對象的成員變量的名稱是一致的!並且,前面在驗證的時候,我們已經把Parameter中帶過來的數據封裝到了FormBean對象中了,所以我們可以使用copyProperties()方法!
- 使用該方法時,值得注意的是:第一個參數是拷貝到哪一個對象上(也就是User對象),第二個參數是被拷貝的對象(也就是formbean對象),口訣:後拷前....不要搞混了!!!!!(我就是搞混了,弄了很久...)
- 處理表單的Servlet完整代碼如下:
//將表單的數據封裝到formBean中
FormBean formBean = WebUtils.request2Bean(request, FormBean.class);
//驗證表單的數據是否合法,如果不合法就跳轉回去註冊的頁面
if(formBean.validate()==false){
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
return;
}
try {
//這是第一種--------------------------
/*User user = new User();
user.setId(WebUtils.makeId());
BeanUtils.copyProperties(user,formBean);*/
//------------------------------------------
//這是第二種
User user1 = WebUtils.request2Bean(request,User.class);
user1.setId(WebUtils.makeId());
//-----------------------------------
//調用service層的註冊方法,實現註冊
ServiceBussiness serviceBussiness = new UserServiceXML();
serviceBussiness.register(user1);
} catch (Exception e) {
e.printStackTrace();
}
現在還有問題,如果我填寫信息不合法,提交給服務器驗證以後,服務器應該告訴用戶哪個信息不合法,而不是直接把跳轉回註冊界面,把所有的信息全部清空,讓用戶重新填寫!
我們應該這樣做:當發現用戶輸入的信息不合法時,把錯誤的信息記錄下來,等到返回註冊頁面,就提示用戶哪裏出錯了!
-
在FormBean對象中添加一個HashMap集合(因爲等會還要根據關鍵字把錯誤信息顯示給用戶!)
-
FormBean的全部代碼如下:
//表單提交過來的數據全都是String類型的,birthday也不例外!
private String username;
private String password;
private String password2;
private String email;
private String birthday;
//記錄錯誤的信息
private HashMap<String, String> error = new HashMap<>();
/*用於判斷表單提交過來的數據是否合法*/
public boolean validate() {
//用戶名不能爲空,並且要是3-8的字符 abcdABcd
if (this.username == null || this.username.trim().equals("")) {
error.put("username", "用戶名不能爲空,並且要是3-8的字符");
return false;
} else {
if (!this.username.matches("[a-zA-Z]{3,8}")) {
error.put("username", "用戶名不能爲空,並且要是3-8的字符");
return false;
}
}
//密碼不能爲空,並且要是3-8的數字
if (this.password == null || this.password.trim().equals("")) {
error.put("password", "密碼不能爲空,並且要是3-8的數字");
return false;
} else {
if (!this.password.matches("\\d{3,8}")) {
error.put("password", "密碼不能爲空,並且要是3-8的數字");
return false;
}
}
//兩次密碼要一致
if (this.password2 != null && !this.password2.trim().equals("")) {
if (!this.password2.equals(this.password)) {
error.put("password2", "兩次密碼要一致");
return false;
}
}
//郵箱可以爲空,如果爲空就必須合法
if (this.email != null && !this.email.trim().equals("")) {
if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {
error.put("email", "郵箱不合法!");
return false;
}
}
//日期可以爲空,如果爲空就必須合法
if (this.birthday != null && !this.birthday.trim().equals("")) {
try {
DateLocaleConverter dateLocaleConverter = new DateLocaleConverter();
dateLocaleConverter.convert(this.birthday);
} catch (Exception e) {
error.put("birthday", "日期不合法!");
return false;
}
}
//如果上面都沒有執行,那麼就是合法的了,返回true
return true;
}
//.....各種的setter和getter
-
在跳轉到註冊頁面之前,把formbean對象存到request域中。在註冊頁面就可以把錯誤的信息取出來(使用EL表達式)!
-
處理表單的Servlet的部分代碼
//驗證表單的數據是否合法,如果不合法就跳轉回去註冊的頁面
if(formBean.validate()==false){
//在跳轉之前,把formbean對象傳遞給註冊頁面
request.setAttribute("formbean", formBean);
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
return;
}
- 在註冊頁面中,使用EL表達式把錯誤的信息寫出來
- 測試:
- 效果:
做到這裏,還是有丟丟的問題,我們不應該把用戶輸入的數據全部清空的!你想想,如果用戶註冊需要輸入多個信息,僅僅一個出錯了,就把全部信息清空,要他重新填寫,這樣是不合理的!
- 我們在各個的輸入項中使用EL表達式回顯數據就行了!
- 效果:
還沒有完善,細心的朋友可以發現,上面圖的日期也是錯誤的,但是沒一次性標記出來給用戶!要改也十分簡單:在驗證的時候,不要先急着return false 用一個布爾型變量記住,最後返回布爾型的變量即可
無論註冊成功還是失敗都需要給用戶一個友好界面的!
5.2登陸界面
登陸和註冊是類似的,我們按着註冊的步驟來寫就對了!
首先寫一個提供登陸界面的Servlet
//直接跳轉到登陸界面
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
- 寫登陸界面
<h1>這是登陸界面</h1>
<form action="${pageContext.request.contextPath}/LoginServlet" method="post">
<table>
<tr>
<td>用戶名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密碼</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" name="重置"></td>
</tr>
</table>
</form>
- 寫處理登陸表單的Servlet
//獲取提交過來的數據
String username = request.getParameter("username");
String password = request.getParameter("password");
//調用service層的方法,去查詢數據庫(XML)是否有該條記錄
try {
ServiceBussiness serviceBussiness = new UserServiceXML();
User user = serviceBussiness.login(username, password);
if (user == null) {
request.setAttribute("message", "用戶名或密碼是錯的");
} else {
request.setAttribute("message","登陸成功");
}
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message","登陸失敗咯");
}
request.getRequestDispatcher("/message.jsp").forward(request, response);
- 效果:
5.3把註冊和登陸都掛在首頁上
<h1>這是首頁!</h1>
<a href="${pageContext.request.contextPath}/LoginUIServlet">登陸</a>
<a href="${pageContext.request.contextPath}/RegisterUIServlet">註冊</a>
</body>
總結
- 使用JSP+JavaBean開發一個簡單計算器,是非常容易的,顯示頁面和請求都是交由JSP來做。沒有什麼新的知識點,用一些JSP行爲就能完成了。
- MVC模式開發使用Servlet來做處理請求,代碼量略大,但層次清晰
- 使用BeanUtils開發組件可以將request請求的參數封裝到JavaBean對象中,Date屬性要另外處理
- 校驗的功能也是使用一個JavaBean來完成,目的就是爲了可重用性,職責分工。同時,我們可以在該JavaBean設置一個Map集合來保存錯誤的信息,以便在前臺上展示錯誤信息。
作者:Java3y
鏈接:https://www.jianshu.com/p/bf71a3367791
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。