本人是一名物聯網工程專業大二的學生,是互聯網浪潮中一朵小小的浪花,寫博客即是爲了記錄自己的學習歷程,又希望能夠幫助到很多和自己一樣處於起步階段的萌新。臨淵羨魚,不如退而結網。一起加油!
博客主頁:https://blog.csdn.net/qq_44895397
請求重定向和轉發
當處理器對請求處理完畢後,向其它資源進行跳轉時,有兩種跳轉方式:請求轉發與重定向。而根據所要跳轉的資源類型,又可分爲兩類:跳轉到頁面與跳轉到其它處理器。
對於請求轉發的頁面,可以是WEB-INF中頁面;而重定向的頁面,是不能爲WEB-INF中頁的。因爲重定向相當於用戶再次發出一次請求,而用戶是不能直接訪問 WEB-INF 中資源的
SpringMVC 框架把原來 Servlet 中的請求轉發和重定向操作進行了封裝。現在可以使用簡單的方式實現轉發和重定向。
- forward:表示轉發,實現request.getRequestDispatcher(“xx.jsp”).forward()
- redirect:表示重定向,實現 response.sendRedirect(“xxx.jsp”)
請求轉發
處理器方法返回 ModelAndView 時,需在 setViewName()指定的視圖前添加 forward:,且此時的視圖不再與視圖解析器一同工作,這樣可以在配置瞭解析器時指定不同位置的視圖。視圖頁面必須寫出相對於項目根的路徑。forward 操作不需要視圖解析器。處理器方法返回 String,在視圖路徑前面加入 forward: 視圖完整路徑。
語法:setViewName(“forward:使徒的完整路徑”);
@RequestMapping("/handlerIntercwptor.do")
public ModelAndView forwardDemo(String name ,Integer age){
ModelAndView mv = new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("forward:/WEB-INF/view/forward.jsp");
return mv;
}
請求重定向
在處理器方法返回的視圖字符串的前面添加 redirect:,則可實現重定向跳轉。
處理器方法定義:
@RequestMapping("/handlerIntercwptor.do")
public ModelAndView redirectDemo(String name ,Integer age){
ModelAndView mv = new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("redirect:/redirect.jsp");
//mv.setViewName("redirect:/WEB-INF/view/forward.jsp");
return mv;
}
異常處理
@ExceptionHandler 註解
使用註解@ExceptionHandler 可以將一個方法指定爲異常處理方法。該註解只有一個可選屬性 value,爲一個 Class<?>數組,用於指定該註解的方法所要處理的異常類,即所要匹配的異常。
而被註解的方法,其返回值可以是 ModelAndView、String,或 void,方法名隨意,方法參數可以是 Exception 及其子類對象、HttpServletRequest、HttpServletResponse 等。系統會自動爲這些方法參數賦值。
對於異常處理註解的用法,也可以直接將異常處理方法註解於Controller 之中
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}
使用步驟:
- 自定義異常類
- 修改Controller拋出異常
- 自定義異常響應頁面
- 自定義一場全局處理類
- 修改配置文件(聲明異常類的存在)
Controller拋出異常:
@RequestMapping("/some.do")
public ModelAndView addStudent(String name, Integer age) throws MyException {
ModelAndView mv = new ModelAndView();
if (!"zs".equals(name)) {
throw new NameException("名字有誤");
}
if(age==null||age>100){
throw new AgeException("年齡異常");
}
mv.addObject("myname", name);
mv.addObject("myage", age);
mv.setViewName("show");
return mv;
}
/**
* @ControllerAdvice :控制器增強,給控制器類增強功能
* 在類上使用
* 需要使用組件掃描器,讓框架知道這個註解所在的包名
*
* 處理異常的方法和控制器方法的定義一樣可以以有多個參數,可以返回ModelAndView
* String,void對象返回值
* 形參:Exception,獲取異常發生的信息
* @ExceptionHandler :異常的class,表示發生異常的類型
*/
@ControllerAdvice
public class MyHandler {
@ExceptionHandler(NameException.class)
public ModelAndView ageExcrption(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","寧輸入的姓名異常");
mv.addObject("message",e.getMessage());
mv.setViewName("ageErorr");
return mv;
}
}
攔截器
SpringMVC 中的 Interceptor 攔截器它的主要作用是攔截指定的用戶請求,並進行相應的預處理與後處理。其攔截的時間點在“處理器映射器根據用戶提交的請求映射出了所要執行的處理器類,並且也找到了要執行該處理器類的處理器適配器,在處理器適配器執行處理器之前”。當然,在處理器映射器映射出所要執行的處理器類時,已經將攔截器與處理器組合爲了一個處理器執行鏈,並返回給了中央調度器。
一個攔截器的執行
- preHandle(request,response, Object handler):
該方法在處理器方法執行之前執行。其返回值爲 boolean,若爲 true,則緊接着會執行處理器方法,且會將 afterCompletion()方法放入到一個專門的方法棧中等待執行。
/**
* preHandle:預處理方法,
* Object handler:被攔截的控制器對象
* 返回值:boolean
* true:表示能夠進入控制方法,
* false:請求被攔截
* 特點:
* 1、方法在控制器方法之前執行
* 2、這個方法中能夠驗證請求的信息,驗證請求是否符合要求
* 驗證失敗可以截斷請求
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle,驗證通過");
return true;
}
- postHandle(request,response,Objecthandler,modelAndView):
該方法在處理器方法執行之後執行。處理器方法若最終未被執行,則該方法不會執行。由於該方法是在處理器方法執行完後執行,且該方法參數中包含 ModelAndView,所以該方法可以修改處理器方法的處理結果數據,且可以修改跳轉方向。
/**
*後處理方法:
* handler :被攔截的處理器對象
* modelAndView:處理器方法的返回值,能夠修改
* 在處理器方法之後進行,沒有返回值
* 能夠獲取處理器返回值,能夠修改視圖和值
* 對執行結果進行二次修正
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
- afterCompletion(request,response, Object handler, Exception ex):
當 preHandle()方法返回 true 時,會將該方法放到專門的方法棧中,等到對請求進行響應的所有工作完成之後才執行該方法。即該方法是在中央調度器渲染(數據填充)了響應頁面之後執行的,此時對 ModelAndView 再操作也對響應無濟於事。
afterCompletion 最後執行的方法,清除資源,例如在 Controller 方法中加入數據
/**
* 最後執行的方法
*
*Exception:程序發生的異常
* 在請求處理完成過後執行,視圖處理完成後,對視圖進行了forward就認爲請求處理完成
* 一般做資源回收工作
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("afterCompletion");
}
攔截器中方法與處理器方法的執行順序如下圖:
多個攔截器的執行
當有多個攔截器時,形成攔截器鏈。攔截器鏈的執行順序,與其註冊順序一致。需要再次強調一點的是,當某一個攔截器的preHandle()方法返回 true 並被執行到時,會向一個專門的方法棧中放入該攔截器的 afterCompletion()方法。
SSM的整合
兩個容器:
- SpringMVC容器,管理Controller對象
- Spring容器,管理service,dao,工具類
實現步驟:
-
建表
-
新建maven項目
-
加入依賴:
SpringMVC,servlet,jsp,jackson,Spring,Spring事務,Spring-MyBatis,Mybatis,mysql驅動,druid連接池 -
web.xml
1)註冊DispatcherServlet,目的:創建springmvc容器,才能創建Controller類對象
2)註冊spring監聽器:ContextLoaderListener,創建spring容器對象,才能創建service,dao等對象
3)註冊字符集過濾器,post請求亂碼 -
創建包,Controller,service,dao,實體類
-
springmvc,spring,mybatis的配置文件
pom.xml:
<dependencies>
<!--添加依賴-->
<!--servlet依賴-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp依賴 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!--springmvc的依賴,自動導入了spring的依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--spring管理事務的依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--jkson的依賴-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--mybatis的依賴,spring-mybatis的依賴,德魯伊連接池-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--Resource註解無法使用-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
spring的主配置文件:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:conf/mybatis.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.yky.dao" />
</bean>
<!--創建出service的對象使用註解完成,添加註解掃描器-->
<context:component-scan base-package="com.yky.service" />
springmvc的配置文件:
- 組件掃描器
- 視圖解析器
- 數據類型轉爲json時用到@ResponseBody註解啓動
能夠解決訪問靜態資源時的衝突問題
<context:component-scan base-package="com.yky.Controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:annotation-driven/>
本站所有文章均爲原創,歡迎轉載,請註明文章出處:愛敲代碼的小遊子