SpringMVC學習筆記
文章目錄
- SpringMVC學習筆記
- SpringMVC概述
-
- SpringMVC 基本說明
- SpringMVC中的核心Servlet---DispatcherServlet
- springmvc請求的處理過程
- web開發中配置檔案說明
- SpringMVC内部執行流程
- SpringMVC 注解式開發
-
- @RequestMapping注解的使用。
- 接受請求中的參數
-
- 逐個接收
- 請求中參數名和形參名不一樣,使用@RequestParam
- 對象接收參數
- 控制器方法的傳回值
-
- 傳回資料和視圖
- 傳回String 視圖
- 傳回值void 沒有資料和視圖
- 傳回值是Object對象
-
- HttpMessageConverter 消息轉換器
- @ResponseBody
- 控制器方法傳回對象轉為json的步驟
- 靜态資源處理
-
- tomcat的default servlet
- 央排程器設定 "/"
- 第一種方式處理靜态資源
- 第二種靜态資源的處理方式
- SSM 整合開發
-
- SSM 整合思路
- 容器的建立
- SSM整合開發步驟
- 相對路徑
- SpringMVC 核心技術
-
- 轉發和重定向
- 異常處理
- 攔截器
-
- 第一個攔截器
- 多個攔截器
- 攔截器和過濾器的對比
SpringMVC概述
SpringMVC 基本說明
SpringMVC是基于spring的, 是spring中的一個子產品,做web開發使用的。
- 說明他是spring的核心技術, 做web開發,springmvc内部是使用mvc架構模式。
- SpringMVC 是一個容器, 管理對象的,使用IoC核心技術。 springmvc管理界面層中的控制器對象。
- SpringMVC底層也是Servlet。 以Servlet為核心, 接收請求,處理請求。 顯示處理結果給使用者。
處理使用者請求的步驟:
使用者發起請求----SpringMVC—Spring—MyBatis–mysql資料庫
SpringMVC中的核心Servlet—DispatcherServlet
1.DispatcherServlet 是架構一個Servlet對象。 負責接收請求, 響應處理結果。
2.DispatcherServlet 他的父類是HttpServlet
3.DispatcherServlet 也叫做前端控制器( front controller)。
4.SpringMVC是管理控制器對象, 原來沒有SpringMVC之前使用 Servlet作為控制器對象使用。現在通過SpringMVC容器建立一種叫做控制器的對象,代替Servlet行駛控制器的角色。功能。
5.SpringMVC 主要使用注解的方式, 建立控制器對象, 處理請求。
springmvc請求的處理過程
簡單的處理過程:
使用者發起請求some.do—>Tomcat接收了請求—DispatcherServlet–配置設定MyController(doSome()傳回mv對象)–mv顯示給使用者了。

web開發中配置檔案說明
1.web.xml 部署描述符檔案 , 給伺服器(tomcat)。
作用:伺服器在啟動的時候,讀取web.xml ,根據檔案中的聲明建立各種對象,根據檔案中的聲明 知道 請求和servlet等對象的關系。
web.xml檔案配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--聲明springmvc的核心對象
通路mymvc位址後, 報錯 檔案沒有找到。找的檔案 /WEB-INF/springmvc-servlet.xml
/WEB-INF/myweb-servlet.xml
錯誤原因:
在Servlet的init()方法中,建立springmvc使用的容器對象WebApplicationContext.
WebApplicationContext ctx = new ClassPathXmlApplicationContext(配置檔案)。
配置檔案的預設路徑: /WEB-INF/<servlet-name>-servlet.xml
-->
<servlet>
<servlet-name>myweb</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>
<!--
表示伺服器tomcat建立對象的順序, 是個整數值, 大于等于0.
數值越小,建立對象的時間越早。
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<!--
url-pattern 作用: 把一些請求交給指定的servlet處理
使用中央排程器(DispatcherServlet)
1. 使用擴充名方式, 格式 *.xxx , xxx是自定義的擴充名。
例如 *.do , *.action, *.mvc 等等. 不能使用*.jsp
http://localhost:8080/myweb/some.do
http://localhost:8080/myweb/user/list/queryUser.do
http://localhost:8080/myweb/user/list/list.do
2. 使用斜杠 "/"
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
2.架構的配置檔案, springmvc的配置檔案
作用:聲明架構建立的項目中的各種對象, 主要是建立Controller對象的
配置檔案的加載順序和功能
3.tomcat伺服器啟動, 讀取web.xml. 根據web.xml檔案中的說明,建立對象。建立DispatcherServlet他的對象, 會執行init()方法。 在init()方法中會執行 springmvc容器對象建立WebApplicationContext ctx = new ClassPathXmlApplicationContext(“classpath:springmvc.xml”)
4.springmvc架構, new ClassPathXmlApplicationContext()讀取springmvc的配置檔案。
//聲明元件掃描器,掃描控制器處理方法所在的包
<context:component-scan base-package="com.bjpowernode.controller" />
使用元件掃描器base-package=“com.bjpowernode.controller” ,周遊controller包中的所有類,MyController類, 找到這個類中的@Controller, @RequestMapping注解, 就能建立MyContoller對象。知道some.do的請求是執行doSome()方法以上 1, 2. 都是項目啟動的過程, 沒有執行任何的使用者請求。使用者發起請求some.do----DispatcherServlet DispatcherServlet裡面有 WebApplicationContext 。WebApplicationContext 裡面有MyController對象。請求some.do ,DispatcherServlet 就知道是 MyController處理的。
SpringMVC内部執行流程
springmvc内部請求的處理過程:
1.使用者發起請求給DispatcherServlet
2.DispatcherServlet把請求(request)交給了 處理器映射器。
3.處理器映射器: springmvc架構中的對象, 需要實作HandlerMapping接口。
4.映射器作用: 從springmvc容器中,擷取控制器對象(MyController),把找到的控制器和攔截器對象都放到處理器執行鍊對象中,儲存,并傳回給中央排程器。(MyController controller = ApplicationContext.getBean())
5.DispatcherServlet把擷取到的處理器執行鍊中的控制器對象,交給了處理器擴充卡
處理器擴充卡:是springmvc架構中的對象, 實作HandlerAdapter接口。
擴充卡作用: 執行控制器的方法, 也就是執行MyController.doSome()方法。得到結果ModelAndView
6.DispatcherServlet把控制器執行結果mv交給了 視圖解析器
視圖解析器: springmvc中的對象,需要實作ViewResolver接口。
視圖解析器作用: 處理視圖的, 組成視圖的完整路徑。 能建立View類型的對象
7.DispatcherServlet調用View類的方法, 把Model中的資料放入到request作用域。 執行request.setAttribute(), 對視圖執行forward()轉發行為, request.getRequestDispather("/show.jsp").forward(request,response)
SpringMVC 注解式開發
@RequestMapping注解的使用。
1.屬性:
value 請求的uri位址。
2.位置:
- 在方法的上面, 必須的。
- 在類的上面作為子產品名稱
@RequestMapping(value ="/some.do")
public ModelAndView doSome(){
...
}
//屬性 method 請求的方式, 使用RequestMehtod類的枚舉,表示請求方式
@RequestMapping(value ="/other.do",method = RequestMethod.POST) public ModelAndView doOther(){
...
}
接受請求中的參數
對應HttpServletRequest, HttpServletResponse, HttpSession 隻需要在控制器方法的形參清單中,定義就可以了。架構會給參數指派, 在控制器方法内部可以直接使用 request,response,session參數。
400 : http status , 表示用戶端異常。 主要是發生在使用者送出參數過程中。
接收請求中的參數方式有: 逐個接收, 對象接收
逐個接收
逐個接收: 請求中的參數名和控制器方法的形參名一樣。按照名稱對象接收參數
Controller接收參數
@RequestMapping(value ="/receive-property.do")
public ModelAndView doPropertyParam(String name, Integer age) {
...
}
接收參數的問題:
1.參數最好使用包裝類型。 例如Integer ,能接收空值情況, 接收的是null
2.架構可以使用String到int ,long, float, double等類型轉換。
3.post請求中有亂碼的問題, 使用字元集過濾器。
字元集過濾器的聲明: 使用
CharacterEncodingFilter
在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>
<init-param>
<!--強制請求(request)對象使用encoding的編碼方式-->
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!--強制應答(response)對象使用encoding的編碼方式-->
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<!--強制所有請求,先經過過濾器處理-->
<url-pattern>/*</url-pattern> </filter-mapping>
請求中參數名和形參名不一樣,使用@RequestParam
/**
* 逐個接收請求參數, 請求中參數名和形參名不一樣
* @RequestParam : 解決名稱不一樣的問題
* 屬性: value 請求中的參數名稱
* required : boolean類型的,預設是true
* true:請求中必須有此參數,沒有報錯。
* false:請求中可以沒有此參數。
* 位置: 在形參定義的前面
* */
@RequestMapping(value ="/receive-param.do")
public ModelAndView doReceiveParam(
@RequestParam(value = "rname",required = false) String name,
@RequestParam(value = "rage",required = false) Integer age) {
...
}
對象接收參數
對象接收: 在控制器方法的形參是java對象, 使用java對象的屬性接收請求中參數值。
要求: java對象的屬性名和請求中參數名一樣。
@RequestMapping("/receive-object.do")
public ModelAndView doReceiveObject(Student student){
System.out.println("MyController的方法doReceiveObject="+student);
ModelAndView mv = new ModelAndView();
mv.addObject("myname", student.getName());
mv.addObject("myage", student.getAge());
mv.setViewName("show"); return mv;
}
控制器方法的傳回值
控制器方法的傳回值表示本次請求的處理結果,傳回值有ModelAndView, String, void , Object,請求的處理結果包含: 資料和視圖。
傳回資料和視圖
當請求的結果有資料和視圖,使用ModelAndView最友善
資料:存放request作用域。
視圖:執行forward轉發操作
傳回String 視圖
架構對傳回值是String,執行的是forward轉發操作。
視圖可以表示為完整視圖路徑, 或者視圖的邏輯名稱
@RequestMapping(value ="/return-string-view.do")
public String doReturnStringView1(HttpServletRequest request,String name, Integer age) {
System.out.println("執行了MyController的doReturnStringView1方法name=");
//傳回結果,forward,轉發到show.jsp
//邏輯名稱, 需要配置視圖解析器
return "show";
}
@RequestMapping(value ="/return-string-view2.do")
public String doReturnStringView2(HttpServletRequest request,String name, Integer age) {
System.out.println("執行了MyController的doReturnStringView2方法name=");
//完整視圖路徑,不能使用視圖解析器 return "/WEB-INF/view/show.jsp";
}
傳回值void 沒有資料和視圖
void: 沒有資料和視圖, 可以使用HttpServletResponse對象輸出資料,響應ajax請求。
@RequestMapping("/return-void-ajax.do")
public void returnVoidAjax(HttpServletResponse response,String name,Integer age) throws IOException {
System.out.println("處理void傳回類型, name="+name+",age="+age);
//調用service得到結果對象
Student student = new Student();
student.setName(name+"同學");
student.setAge(age);
//把對象轉為json
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(student);
System.out.println("伺服器端對象轉為的json==="+json);
//輸出json,響應ajax
response.setContentType("application/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.println(json);
pw.flush();
pw.close();
}
傳回值是Object對象
傳回Student 表示資料,還是視圖。 是以控制器方法傳回對象Object, 用來響應ajax請求。
傳回對象Object ,可以是List, Student , Map ,String ,Integer… 這些都是資料, 而ajax請求需要的是資料。 在ajax請求中,一般需要從伺服器傳回的是json格式的資料, 經常要處理java對象到json的轉換。而且還需要輸出資料響應ajax請求。 架構提供了處理 java對象到json轉換, 還是資料輸出工作。
HttpMessageConverter 消息轉換器
HttpMessageConverter 接口,作用是
1.實作請求的資料轉為java對象,
2.把控制器方法傳回的對象轉為json,xml,text,二進制等不同格式的資料。
public interface HttpMessageConverter {
作用: 檢查clazz這個類型的對象,能否轉為 mediaType表示的資料格式 如果能轉為mediaType表示的類型, 傳回true, 傳回true調用read() / boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
作用: 接收請求中的資料,把資料轉為 clazz表示的對象
T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
作用:檢查clazz這種資料類型,能否轉為mediaType表示的資料格式
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
作用: 把t對象,按照contentType說明的格式,把對象轉為json或者xml
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
}
MediaType:媒體類型,表示網際網路中資料的格式。例如application/json, text/html, image/gif
HttpMessageConverter 接口的實作類:
MappingJackson2HttpMessageConverter : 用jackson工具庫的ObjectMapper把java對象轉為json資料格式
StringHttpMessageConverter : 把字元串類型的資料,進行格式轉換和編碼
怎麼使用實作類:
架構根據控制器方法的傳回類型, 自動查找使用的實作類。
@RequestMapping("/receive-object.do")
public Student doReceiveObject(String name,Integer age){
System.out.println("MyController的方法doReceiveObject=");
Student student = new Student(); student.setName("lisi");
student.setAge(20);
return student;
}
預設情況下: springmvc使用了HttpMessageConveter接口的4個實作類。包括了StringHttpMessageConverter.
需要在springmvc的配置檔案,加入注解驅動的标簽 mvc:annotation-driven. 加入這個标簽後, springmvc項目啟動後,會建立HttpMessageConveter接口的7個實作類對象,包括StringHttpMessageConverter 和 MappingJackson2HttpMessageConverter。
@ResponseBody
@ResponseBody注解的作用,就是把student轉換後的json通過HttpServletResponse對象輸出給浏覽器。
//輸出json,響應ajax
response.setContentType("application/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.println(json);
pw.flush();
pw.close();
@ResponseBody注解作用就上面的代碼的實作
控制器方法傳回對象轉為json的步驟
- pom.xml加入jackson依賴,springmvc架構,預設處理json就是使用jackson
- 在springmvc的配置檔案中,加入注解驅動的标簽mvc:annotation-dirven
- 在控制器方法的上面加入@ResponseBody注解,表示傳回值資料,輸出到浏覽器。
靜态資源處理
tomcat的default servlet
tomcat安裝目錄/conf/web.xml
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
default 叫做預設servlet ,作用:
1.它提供靜态資源的處理
2.它處理所有未映射到其他請求的請求處理
央排程器設定 “/”
使用斜杠 "/" . 導緻中央排程器稱為了預設的default servlet。
需要處理靜态資源和其他的未映射的請求。
預設中央排程器沒有處理靜态資源的控制器對象, 是以靜态資源都是 404 。 some.do這個請求有MyController對象, 是以能通路。
如果項目中 , 中央排程器設定了“/” , 動态資源能通路,靜态資源不能通路。
需要處理靜态資源的通路工作。
第一種方式處理靜态資源
在springmvc的配置檔案加入 mvc:default-servlet-handler标簽,springmvc架構會在項目運作時,加入DefaultServletHttpRequestHandler對象,讓這個對象處理靜态資源的通路。
<mvc:annotation-driven />
<mvc:default-servlet-handler />
第二種靜态資源的處理方式
在springmvc配置檔案中加入一個 mvc:resources标簽, 架構會建立ResourceHttpRequestHandler控制器對象, 使用這個對象處理靜态資源的通路。 不依賴tomcat伺服器。 推薦使用的。
<mvc:annotation-driven />
<!--聲明靜态資源的第二種處理方式
mapping: 通路靜态資源的uri位址, 可以使用通配符(**)。
** : 表示任意的目錄和目錄和資源名稱
location: 靜态資源在項目中的位置, 不要使用/WEB-INF目錄
-->
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />
<!--一句話設定靜态資源-->
<!--<mvc:resources mapping="/static/**" location="/static/" />-->
SSM 整合開發
SSM 整合思路
SSM思路: SpringMVC+ Spring + MyBatis(IBatis), 是以有人叫做SSI整合。 SSM整合是使用三個架構的優勢功能。三個架構對應的三層架構的三層。 SpringMVC是視圖層, Spring是業務層, MyBatis持久層。
SSM 整合,需要把對象交給容器管理, 讓容器去建立項目中要使用的java對象。 現在有兩個容器。
第一個是Spring容器: Spring容器是管理service 和 dao等對象的。 是業務層對象的容器。
第二個是SpringMVC容器:管理控制器對象的。 是視圖層對象。
SSM整合就是把對象交給容器管理。 兩個容器共存。 各自負責管理不同的對象。 把對象聲明到配置檔案中,讓兩個容器建立對象。 spring建立service,dao; springmvc建立controller。
容器的建立
Spring容器建立: 在web.xml聲明了監聽器ContextLoaderListener , 這個功能架構寫好了。功能是建立spring的容器對象 WebApplicationContext. 在建立WebApplicationContext對象時,讀取spring的配置檔案, 讀取檔案的時候,遇到bean标簽或者注解,就能建立service ,dao等對象, 放到容器中。
在Spring的配置檔案中,配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--spring配置檔案:聲明service,dao,工具類等-->
<context:property-placeholder location="classpath:conf/jdbc.properties"/>
<!--聲明資料源,作用是連接配接資料庫-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!--set注入給DruidDataSource提供資料庫資訊-->
<property name="url" value="${jdbc.url}"/>
<property name="password" value="${jdbc.password}"/>
<property name="username" value="${jdbc.username}"/>
</bean>
<!--SqlSessionFactoryBean建立SqlSessionFactory-->
<!-- 聲明的是mybatis中提供的SqlSessionFactoryBean類,這個類内部建立SqlSessionFactory類 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- set注入,把資料庫連接配接池賦給了dataSource屬性 -->
<property name="dataSource" ref="dataSource"/>
<!--
mybatis主配置檔案名的位置
configLocation屬性是Resource類型,讀取配置檔案
他的指派:使用value,指定檔案的路徑,使用classpath:表示檔案的位置
-->
<property name="configLocation" value="classpath:conf/mybatis.xml"/>
</bean>
<!--
聲明mybatis的掃描器,建立dao對象
使用SqlSession的getMapper(StudentDao.class)
MapperScannerConfigurer:在内部調用getMapper()生成每個dao接口的代理對象
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定SqlSession對象的id -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
<!--
指定包名,包名是dao接口所在的包
MapperScannerConfigurer會掃描這個包中的所有接口,把每個接口都執行一次getMapper()方法,
得到每個接口的dao對象。
建立好的dao對象放入到spring的容器中
-->
<property name="basePackage" value="com.zhang.dao"/>
</bean>
<!--聲明service的注解@service所在包的位置-->
<context:component-scan base-package="com.zhang.service"/>
</beans>
SpringMVC容器: 在web.xml聲明了中央排程器DispatcherServlet。 在這個servlet的init()方法中, 建立了容器對象 WebApplicationContext, 在建立WebApplicationContext對象,讀取springmvc的配置檔案, 讀取檔案的時候,遇到@Controller注解,建立控制器controller對象,放到容器中。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.xsd
">
<!--springmvc的配置檔案,聲明controller-->
<!--springmvc的配置-->
<!--掃描所有元件-->
<context:component-scan base-package="com.zhang.controller"/>
<!--聲明視圖解析器:幫助處理視圖-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--字首:指定視圖檔案的路徑-->
<property name="prefix" value="/WEB-INF/view/"/>
<!--字尾:視圖檔案的擴充名-->
<property name="suffix" value=".jsp"/>
</bean>
<!--注解驅動
1.相應ajax請求
2.解決靜态資源通路問題
-->
<mvc:annotation-driven/>
</beans>
記憶體中, 建立對象
WebApplicationContext spring = new WebApplicationContext();
//spring–map(service, dao)
WebApplicationContext springmvc = new WebApplicationContext(); //springmvc–map(controller)
SpringMVC容器和Spring容器的關系: 設計上SpringMVC容器對象是 Spring容器的子容器。
Spring是父容器。 SpringMVC子容器。 相當于java中的繼承關系。
SSM整合開發步驟
1.使用的student表(id,name,age)
2.建立maven web項目
3.修改pom.xml加入依賴: spring ,springmvc,mybatis, mybatis-spring, mysql驅動,druid, jackson
4.寫web.xml : 聲明容器對象
- 聲明spring的監聽器ContextLoaderListener: 建立spring的容器對象, 建立service ,dao對象
- 聲明springmvc的中央排程器DispatherServlet : 建立springmvc容器對象, 建立controller對象
- 聲明字元集的過濾器 CharacterEncodingFilter , 解決post請求亂碼的問題
5.建立程式中的包, dao ,service, controller, entity
6.寫spring,springmvc, mybatis配置檔案
7.寫java代碼, 實體類, dao接口和mapper檔案, service類,controller類。 使用注解聲明對象和指派
8.建立視圖檔案, 各種jsp
相對路徑
在頁面中,有路徑的問題, 通路路徑有 "/"開頭的, 還有沒有 “/”。
位址的差別,現在看的都是在頁面中的位址。
- 有協定開頭的例如http://www.baidu.com , 稱為絕對位址。 位址是唯一的,你能夠直接通路
- 沒有協定開頭的,例如 test/some.do , /test/some.do 稱為相對位址。 相對位址單獨使用不能表示某個資源,不能通路。 相對位址必須有參考位址在一起,才能表示一個資源的完整位址,才能通路。
參考位址: 有“ /" 和沒有”/“ 參考位址不同的。
1)沒有斜杠開頭的位址, 參考位址:目前資源的通路路徑
目前通路的位址: http://localhost:8080/ch07_path/index.jsp
資源名稱: index.jsp
資源路徑: http://localhost:8080/ch07_path
在index.jsp 有 通路位址 a href=“test/some.do”
點選some.do後, 位址變成 http://localhost:8080/ch07_path/test/some.do
此時:http://localhost:8080/ch07path/test/some.do
資源名稱:some.do
資源路徑:http://localhost:8080/ch07path/test/
點選 test/some.do 位址:
//出現問題了
http://localhost:8080/ch07_path/test/test/some.do
解決方式:
1)使用${pageContext.request.contextPath}。
表示通路項目的路徑(上下檔案 context path)
發起請求test/some.do
優點:好了解 缺點:每個連結位址,都需要加el表達式
2)固定目前頁面中的 沒有“/”開頭位址的
參考位址
使用html中base标簽
<% String basePath = request.getScheme() +
"://" + request.getServerName()+
":"+request.getServerPort()+
request.getContextPath()+"/"; %>
2)有斜杠開頭的位址
a href="/test/some.do" target="_blank" rel="external nofollow"
現在通路的的 http://localhost:8080/ch07_path/index.jsp
在index.jsp中有 /test/some.do. 點選/test/some.do,
位址變成 http://localhost:8080/test/some.do
有斜杠開頭的位址,
參考位址是伺服器位址, 也就是從協定開始到端口号的位置 http://localhost:8080
位址組成:http://localhost:8080/test/some.do
位址缺少項目通路路徑, ch07_path.
解決問題的方式:在你的路徑前面加入 el表達式 ${pageContext.request.contextPath}
有/開頭的位址
/test/some.do
SpringMVC 核心技術
轉發和重定向
forward:視圖完整路徑
redirect:視圖完整路徑
轉發和重定向不使用視圖解析器。
重定向不可以通路WEB-INF下的資源檔案。
mv.setViewName("forward:/hello.jsp");
mv.setViewName("redirect:/other.jsp");
異常處理
架構使用的是集中的異常處理。 把各個Controller中抛出的異常集中到一個地方處理。 處理異常的叫做異常處理器。
架構中使用兩個注解完成異常的集中處理。 這樣每個controller不用單獨處理異常了。注解是:
1)@ExceptionHandler : 放在方法的上面,表示此方法可以處理某個類型的異常。 當異常發生時,執行這個方法。
2) @ControllerAdvice: 放在類的上面, 表示這個類中有異常的處理方法。 相當于aop中的@Aspect.
@ControllerAdvice看做是 控制器增強, 就是給Controller類增加異常(切面)的處理功能.
攔截器
攔截器:是springmvc架構中的一種對象, 需要實作接口HandlerInterceptor. 攔截使用者的請求。 攔截到controller的請求。
作用:攔截使用者的請求, 可以預先對請求做處理。 根據處理結果, 決定是否執行controller 。 也可以把多個controller中共用的功能定義到攔截器。
特點:
攔截器可以分為系統攔截器和自定義攔截器。
一個項目可以多個攔截器。0,或多個自定義攔截器。
攔截器側重攔截使用者的請求。
攔截器是在請求處理之前先執行的。
攔截器的定義:
1)建立類實作攔截器接口HandlerInterceptor,實作接口中的方法(3個)
2)在springmvc配置檔案中,聲明攔截器對象,并指定攔截的uri位址
第一個攔截器
public class MyInterceptor implements HandlerInterceptor {
/**
* preHandle: 預先處理請求的方法。
* 參數:
* Object handler : 被攔截的控制器對象(MyController)
* 傳回值: boolean
* true: 請求是正确的,可以被controller處理的。
* =====MyInterceptor攔截器的preHandle====
* 執行了MyController的doSome方法
* =====MyInterceptor攔截器的postHandle====
* =====MyInterceptor攔截器的afterCompletion====
* false: 請求不能被處理, 控制器方法不會執行。 請求到此截止。
* =====MyInterceptor攔截器的preHandle====
* 特點:
* 1. 預處理方法他的執行時間: 在控制器方法之前先執行的。
* 2. 可以對請求做處理, 可以做登入的檢查, 權限的判斷, 統計資料等等。
* 3. 決定請求是否執行。
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=====MyInterceptor攔截器的preHandle====");
return true;
}
/**
* postHandle: 後處理方法
* 參數:
* Object handler : 被攔截的控制器對象(MyController)
* ModelAndView mv: 控制器方法的傳回值(請求的執行結果)
*
* 特點:
* 1. 在控制器方法之後執行的。
* 2. 能擷取到控制器方法的執行結果。 可以修改原來的執行結果。
* 可以修改資料, 也可以修改視圖
* 3. 可以做對請求的二次處理。
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView mv) throws Exception {
System.out.println("=====MyInterceptor攔截器的postHandle====");
}
/**
* afterCompletion: 最後執行的方法
* 參數:
* Object handler : 被攔截的控制器對象(MyController)
* Exception ex: 異常對象
*
* 特點:
* 1. 在請求處理完成後執行的,
* 請求處理完成的标志是 視圖處理完成,對視圖執行forward操作後。
*
* 2. 可以做程式最後要做的工作, 釋放記憶體, 清理臨時變量。
*
* 3. 方法的執行條件:
* 1)目前的攔截器他的preHandle()方法必須執行。
* 2)preHandle()必須傳回true。
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("=====MyInterceptor攔截器的afterCompletion====");
}
配置檔案
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
</mvc:interceptor>
</mvc:interceptors>
多個攔截器
為什麼要使用多個攔截器 ?
把驗證功能分散到獨立的攔截器。 每個攔截器做單一的驗證處理。
組合多個攔截器。
總結:
多個攔截器, 串在一個鍊條上的。 多個攔截器和一個控制器對象在一個鍊條上 ,架構中使用HandlerExecutionChain(處理器執行鍊),表示這個執行鍊條
攔截器和過濾器的對比
1)攔截器是springmvc架構中的對象。 過濾器是servlet中的對象。
2)攔截器對象是架構容器建立的, 過濾器對象是tomcat建立的對象。
3) 攔截器是側重對請求做判斷的,處理的, 可以截斷請求。 過濾器是側重對request,response對象的屬性,參數設定值的。 例如request.setCharacterEncoding(“utf-8”)
4) 攔截器的他執行時間有三個, 控制器方法之前, 之後, 請求完成後。 過濾器是在請求之前。
5)攔截器是攔截對controller,動态資源請求的 。 過濾器可以過濾所有請求動态的和靜态的。
6)攔截器和過濾器一起執行的, 先執行的過濾器,後面是 中央排程器 , 後面才是攔截器, 再後面是控制器方法