簡單跳轉專題
個人建議重新練習一遍搭建的過程,如果感覺麻煩你可以直接復制上一個工程,但是需要修改pom.xml中的一點信息
1
2
3
|
< groupId >com.hanpang.springmvc</ groupId > < artifactId >springmvc-demo01</ artifactId > < version >0.0.1-SNAPSHOT</ version > |
1.核心配置類和加載類
1
2
3
4
5
6
7
8
9
10
|
package com.hanpang.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc @ComponentScan (basePackages= "com.hanpang.**.web" ) public class WebConfig { } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.hanpang.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] {WebConfig. class }; } @Override protected Class<?>[] getServletConfigClasses() { return null ; } @Override protected String[] getServletMappings() { return new String[] { "/" }; } } |
2.JavaWeb階段的跳轉方式
請注意SpringMVC的方法中的形參,框架給我們完成了實例化的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.hanpang.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller //告知其是一個控制器 public class Demo01Controller { @RequestMapping (path= "/test01" ) public ModelAndView 傳統方式跳轉_請求轉發(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { System.out.println( "默認對形參的進行了實例化操作" ); request.getRequestDispatcher( "/WEB-INF/jsp/demo01.jsp" ).forward(request, response); return null ; } @RequestMapping (path= "/test02" ) public ModelAndView 傳統方式跳轉_重定向(HttpServletRequest request,HttpServletResponse response) throws IOException { System.out.println( "默認對形參的進行了實例化操作" ); response.sendRedirect(request.getContextPath()+ "/view/result01.jsp" ); return null ; } } |
NOTE: 這種方式我們幾乎不再使用了,只是只是簡單的演示和回顧一下,至少我們可以使用這種方式獲取Servlet API!!!
3.Controller跳轉到JSP的方式演示
在示例最后的時候,我們會加入JSP的視圖解析器,開始階段我們還是按照傳統的方式,有一個循序漸進的過程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.hanpang.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller //告知其是一個控制器 public class Demo01Controller { @RequestMapping (path= "/test03" ) public ModelAndView 默認情況下是請求轉發(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "/WEB-INF/jsp/demo01.jsp" ); return mav; } @RequestMapping (path= "/test04" ) public ModelAndView 設置重定向的方式(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "redirect:/view/result01.jsp" ); //或者 //mav.setViewName(UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/view/result01.jsp"); return mav; } } |
感覺跟Java Web階段的方式差不多,只是重定向的時候設置了一個簡單的前綴
4.Controller跳轉到Controller的方式演示
類似于從一個Servlet調到另一個Servlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.hanpang.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller //告知其是一個控制器 public class Demo01Controller { @RequestMapping (path= "/test05" ) public ModelAndView 直接設置映射路徑即可(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "/test03" ); return mav; } @RequestMapping (path= "/test06" ) public ModelAndView 設置重定向(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "redirect:/test04" ); return mav; } } |
5.加入JSP的視圖解析器
上面的演示過程中,我們發現ModelAndView中setViewName是用來完成跳轉的,這里面傳遞的數據是字符串,但是處理方式不太一樣,當跳轉的路徑有前綴redirect:的時候,那么處理方式不一樣.
還有,如果我們有多個類似/WEB-INF/jsp/demo01.jsp形式的字符串的時候,我們發現公共的部分很多,SpringMVC給我們提供了一個專門處理 Controller請求轉發JSP頁面 的類.
請注意我的描述: 如果發現你傳遞的字符串沒有設置任何前綴標識,那么默認情況下使用配置JSP視圖解析器處理,并且完成請求轉發的操作
注解:配置核心配置類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package com.hanpang.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration @EnableWebMvc @ComponentScan (basePackages= "com.hanpang.**.web" ) public class WebConfig { @Bean //實例化 public ViewResolver viewResolver() { InternalResourceViewResolver jspViewResolver = new InternalResourceViewResolver(); jspViewResolver.setViewClass(JstlView. class ); //springmvc支持jstl標簽 jspViewResolver.setPrefix( "/WEB-INF/" ); jspViewResolver.setSuffix( ".jsp" ); return jspViewResolver; } } |
**NOTE:**請注意方法上的注解@Bean
方法等價于XML中的代碼如下
1
2
3
4
5
|
< bean id = "jspResourceViewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > < property name = "prefix" value = "/WEB-INF/" /> < property name = "suffix" value = ".jsp" /> < property name = "viewClass" value = "org.springframework.web.servlet.view.JstlView" /> </ bean > |
改進Controller跳轉JSP代碼
該視圖解析器只能針對于JSP的請求轉發,對重定向無效,請注意代碼的注釋內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@RequestMapping (path= "/test03" ) public ModelAndView 默認情況下是請求轉發(){ ModelAndView mav = new ModelAndView(); //mav.setViewName("/WEB-INF/jsp/demo01.jsp"); //改進后:默認情況下,會使用JSP視圖解析器處理, // prefix+"jsp/demo01"+suffix => /WEB-INF/jsp/demo01.jsp mav.setViewName( "jsp/demo01" ); //發現字符串沒有前綴修飾 return mav; } @RequestMapping (path= "/test04" ) public ModelAndView 設置重定向的方式(){ ModelAndView mav = new ModelAndView(); //解析器對重定向無效 mav.setViewName( "redirect:/view/result01.jsp" ); return mav; } |
改進Controller跳轉Controller代碼
1
2
3
4
5
6
|
@RequestMapping (path= "/test05" ) public ModelAndView 直接設置映射路徑即可(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "/test03" ); return mav; } |
當配置完JSP視圖解析器后,對上述的代碼再次進行測試,查看訪問結果有驚喜
符合我們之前說的"/test03"是一個字符串,默認情況下會使用JSP視圖解析器進行處理,那么如何改進呢?
可以設置前綴"forward:",改進代碼如下:
1
2
3
4
5
6
7
8
|
@RequestMapping (path= "/test05" ) public ModelAndView 直接設置映射路徑即可(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "forward:/test03" ); //或者 //mav.setViewName(UrlBasedViewResolver.FORWARD_URL_PREFIX+"/test03"); return mav; } |
當發現字符串使用forward:修飾后,處理情況改變為從Controller請求轉換到另一個Controller,而如果做到重定向的話,代碼如下:
1
2
3
4
5
6
|
@RequestMapping (path= "/test06" ) public ModelAndView 設置重定向(){ ModelAndView mav = new ModelAndView(); mav.setViewName( "redirect:/test04" ); return mav; } |
6.InternalResourceViewResolver 附錄
InternalResourceViewResolver:它是URLBasedViewResolver的子類,所以URLBasedViewResolver支持的特性它都支持。
在實際應用中InternalResourceViewResolver也是使用的最廣泛的一個視圖解析器,那么InternalResourceViewResolver有什么自己獨有的特性呢?
單從字面意思來看,我們可以把InternalResourceViewResolver解釋為內部資源視圖解析器,這就是InternalResourceViewResolver的一個特性。
InternalResourceViewResolver會把返回的視圖名稱都解析為InternalResourceView對象,InternalResourceView會把Controller處理器方法返回的模型屬性都存放到對應的request屬性中,然后通過RequestDispatcher在服務器端把請求forword重定向到目標URL。
比如在InternalResourceViewResolver中定義了prefix=/WEB-INF/,suffix=.jsp,然后請求的Controller處理器方法返回的視圖名稱為test,那么這個時候InternalResourceViewResolver就會把test解析為一個InternalResourceView對象,先把返回的模型屬性都存放到對應的HttpServletRequest屬性中,然后利用RequestDispatcher在服務器端把請求forword到/WEB-INF/test.jsp。這就是InternalResourceViewResolver一個非常重要的特性,我們都知道存放在/WEB-INF/下面的內容是不能直接通過request請求的方式請求到的,為了安全性考慮,我們通常會把jsp文件放在WEB-INF目錄下,而InternalResourceView在服務器端跳轉的方式可以很好的解決這個問題。下面是一個InternalResourceViewResolver的定義,根據該定義當返回的邏輯視圖名稱是test的時候,InternalResourceViewResolver會給它加上定義好的前綴和后綴,組成“/WEB-INF/test.jsp”的形式,然后把它當做一個InternalResourceView的url新建一個InternalResourceView對象返回。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://juejin.im/post/5aa8706ff265da239b411d59