您好,登錄后才能下訂單哦!
Spring Web MVC
Spring Web MVC需要使用IOC功能。
用于開發(fā)MVC結(jié)構(gòu)的Web程序。
一.MVC思想
將程序組件分為模型,視圖,控制器三部分。
二.Spring如何實(shí)現(xiàn)MVC
a.瀏覽器發(fā)出一個(gè)HTTP請(qǐng)求
b.請(qǐng)求首先進(jìn)入DispatcherServlet主控制器
c.主控制器調(diào)用HandlerMapping組件根據(jù)請(qǐng)求找映射的Controller處理
d.執(zhí)行Controller處理方法,將返回結(jié)果給ViewResolver組件
e.ViewResolver組件根據(jù)Controller返回結(jié)果定位視圖JSP,將模型數(shù)據(jù)傳遞給JSP
f.由JSP生成響應(yīng)結(jié)果,給瀏覽器輸出
發(fā)請(qǐng)求到DispatcherServlet,然后到HandlerMapping到Controller1接下來返回一個(gè)ViewResolver到視圖。
eg:頁面上發(fā)出hello.do請(qǐng)求,首先經(jīng)過web.xml,知道.do請(qǐng)求需要進(jìn)入到DispatcherServlet,DispatcherServlet去applicationContext.xml里面
尋找handlerMapping組件,根據(jù)mapping名為hello.do找hello.do找helloController組件處理。根據(jù)helloController里的ModelAndView和applicationContext.xml的prefix和suffix配置去找到/WEB-INF/hello.jsp
eg1:顯示登錄頁面
/tologin.do
—>DispatcherServlet(配置)//充當(dāng)主控制器,發(fā)請(qǐng)求時(shí)先給他
—>hanlderMapping(配置)//定義Servlet請(qǐng)求和Controller對(duì)應(yīng)關(guān)系,根據(jù)applicationContext.xml配置解析對(duì)應(yīng)的哪一個(gè)Controller
—>toLoginController(編寫+配置)//調(diào)用DAO模型組件
—>ViewerResolver(配置)//封裝,轉(zhuǎn)發(fā),重定向到JSP視圖
—>WEB-INF/login.jsp(編寫)
3.Spring Web MVC處理流程
a.RequestMappingHandlerMapping組件
@RequestMapping(“l(fā)ogin.do”)該標(biāo)記用在Controller業(yè)務(wù)方法前
b.Controller編寫和配置
取消了實(shí)現(xiàn)Controller接口及方法約定,可以允許程序員按需靈活定義業(yè)務(wù)方法;
public ModelAndView或String 方法名(根據(jù)request,session,response)
Controller需要掃描到Spring容器,必須使用@Controller
eg: public String execute(){
return “hello”;
}
d.Controller如何接收請(qǐng)求參數(shù)
1)利用HttpServletRequest
*2)利用業(yè)務(wù)方法參數(shù)(少量參數(shù)時(shí)使用)
*--參數(shù)名與請(qǐng)求參數(shù)key保持一致
—利用@RequestParam(“key")
*3)利用實(shí)體對(duì)象當(dāng)方法參數(shù)(大量參數(shù)時(shí)使用)
使用建議:少量參數(shù)使用2);大量參數(shù)使用3);如果客戶端表單數(shù)據(jù)沒有格式檢查,遇到非字符串類型參數(shù)建議使用1)
e.如何向響應(yīng)JSP傳值
*1)利用HttpServletRequest
2)利用ModelAndView做返回值
*3)利用ModelMap方法參數(shù)
4)使用@ModelAttribute(“key")
public String checkLogin(@ModuleAttribute(“user”) String username){
return “ok”;}//ok.jsp使用${user}
@ModelAttribute(“user")
public String getName(){
return “tom”;}
等價(jià)于model.put(“user”, getName());//${user}即tom
f.Controller如何使用Session
代碼示例:
web.xml:
<servlet> <servlet-name>webLogin2</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>webLogin2</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
handlermapping和controller:
@Controller public class LoginController { //登錄按鈕處理 @RequestMapping("/login.do") public String checkLogin3(String username, String password, ModelMap modelMap, HttpSession session){ if ("root".equals(username) && "1234".equals(password)){ modelMap.put("user", username); session.setAttribute("username", username); return "ok";//ok.jsp 使用${user} } else { modelMap.put("msg", "用戶名或密碼錯(cuò)誤"); return "login";//login.jsp使用${msg} } }
spring配置:
<!--等價(jià)于handlermapping--> <mvc:annotation-driven></mvc:annotation-driven> <context:component-scan base-package="controller"> </context:component-scan> <!--配置viewerResolver--> <bean id="viewresolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--去prefix配置下找頁面--> <property name="prefix" value="/WEB-INF/"> </property> <!--提取出.jsp結(jié)尾文件,文件名為Controller中ModelAndView返回的名字--> <property name="suffix" value=".jsp"> </property> </bean>
ok.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> </head> <body> <form action="ok.do" method="post"> <h3>${user} login success</h3> session內(nèi)容: ${sessionScope.username} </form> </body> </html>
login.jsp:
<%@ page language="java" pageEncoding="UTF-8"%> <html> <head> </head> <body> <h3>用戶登錄</h3> ${msg} <form action="login3.do" method="post"> 用戶名:<input type="text" name="username"><br/> 密碼:<input type="password" name="password"><br/> <input type="submit" value="登錄"> </form> </body> </html>
訪問:http://localhost:8090/webLogin2_war(此處為自己定義的war包名)/login.do
用正確的用戶名密碼進(jìn)入顯示:
session內(nèi)容: root
4.Spring Web MVC
1) 解決中文接收亂碼問題
<!--spring mvc解決中文亂碼-->
<filter>
<filter-name>myfilter</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>myfilter</filter-name>
<url-pattern>*.do</url-pattern>
<!--或者寫<servlet-name>webLogin2</servlet-name>-->
</filter-mapping>
2)如何處理異常
a.全局異常處理:SimpleMappingExceptionResolver
@Controller public class ExceptionController { @RequestMapping("/exception.do") public String ex(){ String s = null; s.length(); return "ok"; } }
此時(shí)訪問exception.do會(huì)拋出nullpoint異常,需要進(jìn)行異常處理,使用內(nèi)置的全局異常處理方法
applicationContext.xml配置:
<!--異常處理器--> <!--<prop key="異常類型">視圖名</prop>--> <!--拋出異常后得到error視圖名傳遞給viewResolver--> <!--<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.Exception">error</prop> </props> </property> </bean>-->
此時(shí)處理流程圖:
b.局部異常處理:@ExceptionHandler
public String xxx(HttpServletRequest request, Exception e){}
@Controller public class AgeController { @RequestMapping("/toage.do") public String toage(){ //檢查session里是否有username return "age";//進(jìn)入age.jsp } @RequestMapping("/age.do") public String age(String birth, ModelMap modelMap) throws Exception { //接收用戶輸入的生日,計(jì)算年齡 Date now = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD"); Date birth2 = sdf.parse(birth); int result = now.getYear() - birth2.getYear(); modelMap.put("msg", "年齡為: " + result); return "age";//進(jìn)入age.jsp,${msg} //當(dāng)出現(xiàn)異常時(shí)無法返回String故進(jìn)入handleException方法 } /*當(dāng)前Controller異常處理, * 當(dāng)執(zhí)行該方法后,不會(huì)再調(diào)用ExceptionResolver */ @ExceptionHandler//局部異常處理方法 public String handleException(HttpServletRequest request, Exception e) { request.setAttribute("msg", "輸入信息有誤導(dǎo)致計(jì)算失敗"); return "age";//返回age.jsp } }
c.自定義ExceptionResolver(實(shí)現(xiàn)HandlerExceptionResolver接口)
先寫自己的異常處理類:
public class MyExceptionHandler implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object method, Exception e) { //將異常信息寫入文件 System.out.println("將異常信息寫入文件: " + e); //跳轉(zhuǎn)到錯(cuò)誤頁面 ModelAndView mav = new ModelAndView(); mav.setViewName("error"); return mav; } }
eorror.jsp
<%@ page language="java" pageEncoding="UTF-8" %> <html> <head> </head> <body> <h3>系統(tǒng)繁忙</h3> </body> </html>
注釋掉applicationContext.xml中的全局異常處理,寫上自己的異常處理類:
<!--使用自定義的ExceptionResolver, 訪問exception.do--> <bean class="controller.MyExceptionHandler"> </bean>
此時(shí)訪問exception.do當(dāng)程序出錯(cuò)時(shí)頁面將顯示系統(tǒng)繁忙字樣
3)如何實(shí)現(xiàn)登錄權(quán)限檢查
使用session進(jìn)行約定值判斷。
實(shí)現(xiàn)方法:1.采用Filter(通用解決方法);2.采用攔截器(Spring WEB MVC)
a.攔截器組件簡(jiǎn)介
攔截器組件時(shí)SpringMVC特有組件。
攔截器組件可以在Controller之前攔截;可以在Controller之后攔截;可以在JSP解析完畢給瀏覽器輸出之前攔截。
b.攔截器使用方法
首先編寫一個(gè)攔截器組件(實(shí)現(xiàn)HandlerInterceptor接口)
在約定方法中添加要插入的邏輯然后在applicationContext.xml中配置
攔截器類:
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class LoginInterceptor implements HandlerInterceptor { @Override //controlller之前,權(quán)限檢查,登錄檢查 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("---preHandle實(shí)現(xiàn)登錄檢查---"); HttpSession session = request.getSession(); //獲取登錄成功后放置的用戶信息 String name = (String) session.getAttribute("username"); if (name != null) {//登錄過 return true;//繼續(xù)執(zhí)行mvc后續(xù)流程 } else {//登錄失效(session失效)或登錄失敗 response.sendRedirect("/tologin.do"); return false;//終止mvc后續(xù)流程 } } @Override //controller之后,統(tǒng)計(jì)請(qǐng)求到處理開始到完畢的日志,執(zhí)行的時(shí)間性能監(jiān)控,檢查耗時(shí)項(xiàng) public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("---postHandle---"); } @Override //請(qǐng)求處理完畢,輸出之前。統(tǒng)計(jì)請(qǐng)求到處理開始到完畢的日志,執(zhí)行的時(shí)間性能監(jiān)控,檢查耗時(shí)項(xiàng) public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---afterHandle---"); } }
applicationContext.xml
<!--配置攔截器--> <mvc:interceptors> <mvc:interceptor> <!--攔截哪些請(qǐng)求--> <!--<mvc:mapping path="toage.do"/>--> <mvc:mapping path="/**/"/> <!--放過哪些請(qǐng)求--> <mvc:exclude-mapping path="/tologin.do"/> <mvc:exclude-mapping path="/login3.do"/> <bean class="controller.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。