本篇運用springmvc來試着寫一個登錄注冊頁面
在動手之前,我們需要了解下springnvc.這里先獻上一張springmvc的流程圖及講解。
Spring的MVC框架是一個基於DispatcherServlet的MVC框架,主要由DispatcherServlet、處理器映射、處理器、視圖解析器、視圖組成。每一個請求最先訪問的都是DispatcherServlet,DispatcherServlet負責轉發每一個Request請求給相應的Handler,Handler處理以后再返回相應的視圖(View)和模型(Model),返回的視圖和模型都可以不指定,即可以只返回Model或只返回View或都不返回。
Spring MVC的原理框圖:
整個處理過程從一個HTTP請求開始:
1)DispatcherServlet接收到請求后,根據對應配置文件中配置的處理器映射,找到對應的處理器映射項(HandlerMapping),根據配置的映射規則,找到對應的處理器(Handler)。
2)調用相應處理器中的處理方法,處理該請求,處理器處理結束后會將一個ModelAndView類型的數據傳給DispatcherServlet,這其中包含了處理結果的視圖和視圖中要使用的數據。
3)DispatcherServlet根據得到的ModelAndView中的視圖對象,找到一個合適的ViewResolver(視圖解析器),根據視圖解析器的配置,DispatcherServlet將視圖要顯示的數據傳給對應的視圖,最后給瀏覽器構造一個HTTP響應。
DispatcherServlet是整個Spring MVC的核心。它負責接收HTTP請求組織協調Spring MVC的各個組成部分。其主要工作有以下三項:
1)截獲符合特定格式的URL請求。
2)初始化DispatcherServlet上下文對應的WebApplicationContext,並將其與業務層、持久化層的WebApplicationContext建立關聯。
3)初始化Spring MVC的各個組成組件,並裝配到DispatcherServlet中
此時,我們已經對springmvc有了一定的了解,如果您對還理不清思路,沒關系,下面讓我們來進行實戰演練,邊練邊學。
首先,讓我們梳理下整體步驟:
1)導入包:springframework-3.0.RELEASE全部的包,servlet-api.jar,spring-webmvc.jar,spring.jar,comoms-logging.jar,jstl.jar
2)配置/WEB-INF下的web.xml,spring配置文件spring-servlet.xml,上下文applicationContext.xml
3)創建相關類:
4)創建/WEB-INF/jsp下的jsp頁面
開始配置XML文件!
web.xml
這里我們定義了請求分發Servlet,即:org.springframework.web.servlet.DispatcherServlet
DispatcherServlet 是Spring MVC 中負責請求調度的核心引擎,所有的請求將由此Servlet 根據配置分發至各個邏輯處理單元。其內部同時也維護了一個ApplicationContext實例。
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>mvc_loginregist</display-name> <!-- servlet定義 --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 可以自定義servlet.xml配置文件的位置和名稱,默認為WEB-INF目錄下,名稱為[<servlet-name>]-servlet.xml,如spring-servlet.xml <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> --> <!-- 設置啟動的優先級,這里表示表示啟動容器時初始化該Servlet --> <load-on-startup>1</load-on-startup> </servlet> <!--通過將DispatcherServlet映射到/,聲明了它會作為默認的servlet並且會處理所有請求,包括對靜態資源的請求--> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置ContextLoaderListerner --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 可以配置contextConfigLocation初始化參數 <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/court-servlet.xml</param-value> </context-param> 默認初始化參數為 <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> 這里使用默認參數 --> <!-- 跳轉至首頁,首頁訪問地址為http://localhost:8080/項目名--> <welcome-file-list> <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file> </welcome-file-list> </web-app>
sping-servlet.xml
InternalResourceViewResolver在web應用程序的war文件中查找視圖模板。視圖模塊的路徑根據加完前綴和后綴的邏輯視圖名稱來確定,若返回“login”作為邏輯試圖名稱時,它最終會被解析成"/WEB-INF/jsp/login.jsp"路徑
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- ViewResolver 指定了表現層資源的前綴和后綴 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!--配置處理器映射--> <bean id="loginMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="doLogin">loginAction</prop><!-- 首字母必須小寫,請求"doLogin"對應loginAction處理 --> <prop key="doRegist">registAction</prop> <prop key="toRegist">toRegistAction</prop> <prop key="toLogin">toLoginAction</prop> </props> </property> </bean> </beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- 定義ToRegistAction --> <bean id="toRegistAction" class="com.htgy.actions.ToRegistAction"> </bean> <!-- 定義ToLoginAction --> <bean id="toLoginAction" class="com.htgy.actions.ToLoginAction"> </bean> <!-- 添加處理器配置 --> <!---定義LoginAction類--> <bean id="loginAction" class="com.htgy.actions.LoginAction"> <property name="commandClass"> <value>com.htgy.loginform.LoginForm</value> </property> <!-- 指定失敗要返回的頁面 --> <!-- 需修改 --> <property name="lFailView"> <value>loginFail</value> </property> <!-- 指定成功要返回的頁面 --> <property name="lSuccessView"> <value>loginSuccess</value> </property> </bean> <!-- 定義RegistAction --> <bean id="registAction" class="com.htgy.actions.RegistAction"> <property name="commandClass"> <value>com.htgy.registform.RegistForm</value> </property> <!-- 注冊成功返回的頁面 --> <property name="rSuccessView"> <value>registSuccess</value> </property> <!-- 取消注冊返回的頁面 --> <property name="rFailView"> <value>registFail</value> </property> </bean> </beans>
下面是java類
LoginAction和RegistAction類繼承了SimpleFormController,它是AbstractFormController的具體實現其功能是從表單中提取參數封裝到command。
LoginAction類
package com.htgy.actions; /* * 登錄Controller層 */ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.SimpleFormController; import com.htgy.loginform.LoginForm; public class LoginAction extends SimpleFormController { private String lFailView; private String lSuccessView; public String getLFailView() { return lFailView; } public void setLFailView(String lFailView) { this.lFailView = lFailView; } public String getLSuccessView() { return lSuccessView; } public void setLSuccessView(String lSuccessView) { this.lSuccessView = lSuccessView; } @Override protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { //講表單的參數封裝到command中 LoginForm lf = (LoginForm)command; if (lf.getAccount().equals("111111") && lf.getPassword().equals("123456")){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("LoginForm", lf); List<String> msgList = new LinkedList<String>(); msgList.add("你好,Spring MVC"); map.put("msg", msgList); System.out.println("登錄成功"); //返回視圖和模型,this.getLSuccessView()為視圖,map為模型 return new ModelAndView(this.getLSuccessView(),map); }else{ return new ModelAndView(this.getLFailView()); } } }
RegsitAction類
package com.htgy.actions; /* * 注冊Controller層 */ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.SimpleFormController; import com.htgy.registform.RegistForm; public class RegistAction extends SimpleFormController{ private String rFailView; private String rSuccessView; public String getRFailView() { return rFailView; } public void setRFailView(String rFailView) { this.rFailView = rFailView; } public String getRSuccessView() { return rSuccessView; } public void setRSuccessView(String rSuccessView) { this.rSuccessView = rSuccessView; } @Override protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { //講表單的參數封裝到command中 RegistForm rf = (RegistForm)command; if (rf.getAccount().equals("111111") && rf.getPassFirst().equals("123456") &&rf.getPassSecond().equals("123456")){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("LoginForm", rf); List<String> msgList = new LinkedList<String>(); msgList.add("你好,Spring MVC"); map.put("msg", msgList); //返回視圖和模型,this.getRSuccessView()為視圖,map為模型 return new ModelAndView(this.getRSuccessView(),map); }else{ return new ModelAndView(this.getRFailView()); } } }
SimpleFormController類中的onsubmit方法用於獲取表單傳遞的信息
ToLoginAction類
package com.htgy.actions; /* * 跳轉到login.jsp頁面 */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class ToLoginAction implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { return new ModelAndView("login"); } }
ToRegistAction類
package com.htgy.actions; /* * 跳轉到regist.jsp頁面 */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class ToRegistAction implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { return new ModelAndView("regist"); } }
Controller接口僅僅聲明了一個方法handleRequest,它負責處理請求並返回合適的模型和視圖。
LoginForm類
package com.htgy.loginform; /* * 登錄表單類 */ public class LoginForm { private String account; private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } }
RegistForm類
package com.htgy.registform; /* * 注冊表單類 */ public class RegistForm { private String account; private String passFirst; private String passSecond; public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassFirst() { return passFirst; } public void setPassFirst(String passFirst) { this.passFirst = passFirst; } public String getPassSecond() { return passSecond; } public void setPassSecond(String passSecond) { this.passSecond = passSecond; } }
表單類必須具有set和get方法,便於請求的封裝和提取。
jsp頁面
login.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登錄</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> <h1>登陸</h1> <hr> <% request.setCharacterEncoding("utf-8"); //解決中文亂碼問題 %> <form name="regForm" action="doLogin" method="post"> <table> <tr> <td>賬號:</td> <td><input type="text" name="account" /> </td> </tr> <tr> <td>密碼:</td> <td><input type="password" name="password" /> </td> </tr> </table> <table> <tr> <td colspan="1"><input type="submit" value="登錄" /></td> <td colspan="1"><input type="reset" value="重置" /></td> </tr> </table> </form> <br>還沒有賬號?請注冊<input type="button" value="注冊" onclick="window.location.href='toRegist'"/> </center> </body> </html>
loginFail.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登錄失敗</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> 登錄失敗<a href="toLogin">返回登錄界面</a> </center> </body> </html>
loginSuccess.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登錄成功</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> <h1>登陸成功!!!!!!!!!!</h1> <hr> </center> </body> </html>
regist.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>注冊</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> <% request.setCharacterEncoding("utf-8"); //解決中文亂碼問題 %> <h1>注冊</h1><hr> <form name="regform" action="doRegist" method="post"> <table> <tr> <td>賬號:</td> <td><input type="text" name="account" id="account" maxLength="10"></td> </tr> <tr> <td>密碼:</td> <td><input type="password" name="passFirst" id="passFirst" maxLength="12" /> </td> </tr> <tr> <td>確認密碼:</td> <td><input type="password" name="passSecond" id="passSecond" maxLength="12" /> </tr> <tr> <td>用戶名:</td> <td><input type="text" name="username" maxLength="9"/></td> </tr> </table> <table> <tr> <td colspan="1"><input type="submit" value="注冊" /></td> <td colspan="1"><input type="reset" value="重置" /></td> </tr> </table> </form> <form name="regForm" action="toLogin"> <table> <tr> <td colspan="2"><input type="submit" value="返回登錄界面" /> </td> </tr> </table> </form> </center> </body> </html>
registFail.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>注冊失敗</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> 注冊失敗<br> <a href="toRegist">繼續注冊</a> <a href="toLogin">返回登錄界面</a> </center> </body> </html>
registSuccess.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>注冊成功</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <center> <h1>恭喜您!注冊成功</h1><hr> 返回登陸頁面?<a href="toLogin"/>確定</a> </center> </body> </html>
大功告成!~
本篇只是讓大家初步了解了springmvc的構建和運行原理,之后我們再通過加入數據庫來進行更深層次的了解。
總結:
1)在最開始接觸springmvc時候,經常會把請求和視圖搞反,正確的理解應該是客戶傳遞請求給dispatcherServlet,dispatcherServlet處理請求后再將相應的視圖傳遞給客戶。