SpringMVC開發入門講義
整個實現過程中:
用戶請求的往往是服務器的一個處理程序,這個處理程序會調用後臺的數據處理。最終會把處理後的數據交付到頁面上。
開發規則:單一職責,開閉職責。
MVC的設計模式,優點,將這個請求和響應分為了控制器,數據,視圖三者,這三者彼此之間是獨立。但是三者之間有關聯。每次用戶請求的時候經過統一的控制器處理,最終響應給客戶的就是視圖。耦合性降低,維護的難度降低。
2.MVC的框架,這個框架將我們的Web開發進行整合,整合有一個總的核心的控制器,然後其它的控制器都受它的控制。
SpringMVC是Spring中的一個子框架,包含了我們Web開發的時候所采用的MVC的設計模式的實現解決方案。
3.實現第一個SpringMVC的開發:
1)SpringMVC加入到Spring框架裏。
a.如何將applicationContext.xml設置為當我們的web啟動的時候,就自動加載到內存中。在web.xml裏做配置:
<!-- 對web服務器采取監聽,監聽的目的就是一旦web服務器啟動,那麽就加載spring的配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
2)開發一個針對SpringMVC框架的配置文件,springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd" default-autowire="byName" > </beans>
3)那麽既然springmvc.xml,springmvc.xml也要隨著web服務器的啟動而自動加載。
註意:1)關於前端控制器中的url路徑的匹配為什麽會采用*.action.
如果是采用/*,那麽會將由控制器轉發的jsp頁面也會進入到前端控制器的攔截中,然後會映射相應的控制器,
這樣就會導致找不到相應的控制器出錯。
<!-- 隨著web服務器的加載,前端控制器(中央控制器就要初始化,並且開始工作了) --> <servlet> <servlet-name>springmvc2</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- load-on-startup 的值大於0就表示隨著服務器啟動,這個servlet就自動被初始化 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc2</servlet-name> <url-pattern>*.action</url-pattern><!--配置的訪問路徑,一定是按照這種格式寫 --> </servlet-mapping>
4)開發控制器,該控制器繼承自Controller
public class TestController implements Controller { @Autowired private UserInfoService userInfoService; public UserInfoService getUserInfoService() { return userInfoService; } public void setUserInfoService(UserInfoService userInfoService) { this.userInfoService = userInfoService; } @Override public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { // TODO Auto-generated method stub UserInfo user = new UserInfo(); List<UserInfo> userInfoList = userInfoService.getlist(user); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("userlist",userInfoList); modelAndView.setViewName("/index.jsp"); return modelAndView; } }
5)將springmvc.xml裏做配置,該配置將開發的bean對象加入到spring中:
<!-- 把控制器交付給spring管理 --> <bean name="/getusers.action" class="com.jinglin.hotelsup.controller.TestController"></bean> <!-- handler路徑適配器,將url的路徑同bean裏的name進行比對 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <!-- 視圖解析的bean對象 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
6)頁面通過jstl解析從控制器裏傳出的數據
<c:forEach items="${userlist}" var="user"> 姓名:${user.username} </c:forEach>
執行的流程圖:
整個SpringMVC的執行流程:
1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;
2. DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然後根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;
3. DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附註:如果成功獲得HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法)
4. 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作:
HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
5. Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
6. 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
7. ViewResolver 結合Model和View,來渲染視圖
8. 將渲染結果返回給客戶端。
Spring工作流程描述
為什麽Spring只使用一個Servlet(DispatcherServlet)來處理所有請求?
詳細見J2EE設計模式-前端控制模式
Spring為什麽要結合使用HandlerMapping以及HandlerAdapter來處理Handler?
符合面向對象中的單一職責原則,代碼架構清晰,便於維護,最重要的是代碼可復用性高。如HandlerAdapter可能會被用於處理多種Handler。
5.實際項目中開發SpringMVC,是通過註解的方式開發
一個功能模塊------->一個控制器
開發的時候,在springmvc.xml裏配置:
<!-- 用註解的方式開發控制器 --> <context:annotation-config> <mvc:annotation-driven> </mvc:annotation-driven> </context:annotation-config> <!-- 引入解析jstl的類 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean> <!-- 將控制器的包掃描到spring裏 --> <context:component-scan base-package="com.jinglin.hotelsup.controller"></context:component-scan>
2)開發控制器的類:
@Controller public class UserInfoController { @Autowired private UserInfoService userInfoService; @RequestMapping(value="/login.action",method=RequestMethod.POST) public String userlogin(HttpServletRequest request, HttpSession session){ //request.setCharacterEncoding("utf-8"); //獲取前臺傳入來的數據 String username = request.getParameter("username"); String userpwd = request.getParameter("userpwd"); UserInfo userInfo = new UserInfo(); userInfo.setUsername(username); userInfo.setUserpwd(userpwd); //調用service層,得到業務數據 List<UserInfo> list=userInfoService.getlist(userInfo); if(list!=null){ if(list.size()>0){ UserInfo u = list.get(0); session.setAttribute("user",u); return "redirect:index.jsp"; }else{ request.setAttribute("info","用戶名或密碼輸入錯誤!"); return "forward:login.jsp"; } }else{ return null; } } }
3)解決提交的時候的亂碼問題:POST提交(配置在web.xml裏)
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
SpringMVC開發入門講義