Java充电社
专辑
博文
联系我
本人继续续收门徒,亲手指导
SpringMVC教程
-> 返回页面常见的5种方式
1、Helloword
2、@Controller、@RequestMapping
3、接口测试利器
4、如何接受请求中的参数?
5、@RequestBody接收Json格式数据
6、多文件上传
7、返回页面常见的5种方式
8、返回json格式数据 & 通用返回值设计
9、SpringMVC返回null是什么意思?
10、异步处理请求
11、如何集成静态资源?
12、拦截器怎么用?
13、统一异常处理
14、实战篇:通用返回值 & 异常处理设计
15、全注解的方式 & 原理解析
16、源码解析SpringMVC处理请求的流程
17、源码解析SpringMVC容器的启动过程
18、RequestBodyAdvice:对@ReuqestBody进行增强
19、ResponseBodyAdvice:对@ResponseBody进行增强
20、RESTful接口详解
21、接口调用利器RestTemplate
22、参数解析器HandlerMethodArgumentResolver解密
23、@RequestParam用法及原理详解
24、@RequestBody原理解密
25、@RequestHeader详解
26、@CookieValue详解
27、@RequestAttribute详解
28、@SessionAttribute详解
29、重定向和转向详解
30、Converter转换器详解
31、跨域问题详解
32、类容协商,颠覆你的认知
33、终章
34、CORS通信
35、浏览器安全策略 & CORS
36、Http中的Content-Type详解
上一篇:多文件上传
下一篇:返回json格式数据 & 通用返回值设计
<div style="display:none"></div> **大家好,我是路人,本文如果对你有帮助,点个在看,顺便忙转发一下,非常需要大家的支持,对java有兴趣的朋友欢迎加我微信itsoku交流。** 当http请求被自定义的controller处理时,如何指定响应的页面呢? 这个就是我们本文需要讨论的问题。 在controller中响应页面有很多种方式,稍后我们会一一介绍,大家需要掌握每种方式的用法以及这些方式之间的区别,以后能够灵活使用。 本文用到的页面我都以jsp为例,其他页面模板技术,比如freemarker、velocity、thymeleaf、enjoy,这些我们后面专门再开篇讲解。 ## 1、本文内容 - SpringMVC 返回页面的3种方式及区别 - SpringMVC 重定向的2种方式及区别 ## 2、软件版本 - idea 2020.3.3 - jdk1.8 - ≥maven3.6.1 - spring5.3.6 - apache-tomcat-9.0.46 ## 3、先来回顾下servlet中响应页面的2种方式 SpringMVC底层是依靠servlet来实现的,所以我们先回顾下servlet中响应页面是如何实现的。 servlet中响应页面有2种常见的方式,而springmvc中通常也是依靠这2种方式实现的。 ### 方式1:转向 ```java request.getRequestDispatcher(path).forward(request,response); ``` > 1、path为转向的地址 > > 2、发生在服务器端,浏览器的地址栏不会发生变化 > > 3、path指定的页面,可以共享request请求中的数据 > > 4、path必须是服务器端的资源 ### 方式2:重定向 ``` response.sendRedirect(location); ``` > 1、location为重定向的地址 > > 2、重定向发生在客户端(浏览器端),所以会导致浏览器地址栏发生变化,变为location指定的地址 > > 3、重定向会导致浏览器重新向服务器端发生一次请求,请求地址为location指定的地址 > > 4、location可以为本服务器端的资源,也可以为外网可以访问的任意资源,比如:http://www.baidu.com 下面来详解springmvc中响应页面的5种方式。 ## 4、方式1:返回ModelAndView ### 需求 通过springmvc显示用户列表,如下图 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/9b0d428d-5e07-4638-83e8-19c86234ba4c.png) ### 如何实现? 我们先来看一下如果用servlet是如何实现的,伪代码如下: ```java 1、List<UserDto> userList = new ArrayList(); 2、request.setAttribute("userList",userList); 3、request.getRequestDispatcher("/WEB-INF/view/user/list.jsp").forward(request,response); ``` 关键代码就这几行,相当简单。 对应的jsp(/WEB-INF/view/user/list.jsp)关键代码如下,主要就是一个循环遍历用例列表userList,然后显示 ```html <table border="1" cellpadding="10" cellspacing="0"> <tr> <th width="50">id</th> <th width="100">name</th> <th width="50">age</th> </tr> <c:forEach items="${userList}" var="user"> <tr align="center"> <td>${user.id}</td> <td>${user.name}</td> <td>${user.age}</td> </tr> </c:forEach> </table> ``` ### 使用springmvc实现 ```java @Controller public class UserController { /** * 用户列表(用户id->用户信息) */ Map<Long, UserDto> userDtoMap = new ConcurrentHashMap<>(); { userDtoMap.put(1L, new UserDto(1L, "路人", 30)); userDtoMap.put(2L, new UserDto(2L, "张三", 20)); userDtoMap.put(3L, new UserDto(3L, "李四", 18)); } /** * 用户列表 * * @return */ @RequestMapping("/user/list.do") public ModelAndView list() { //1.创建ModelAndView ModelAndView modelAndView = new ModelAndView(); //2.将所有用户信息放到Model中 modelAndView.addObject("userList", userDtoMap.values()); //3.设置显示的页面 modelAndView.setViewName("/WEB-INF/view/user/list.jsp"); //4.返回ModelAndView return modelAndView; } } ``` 这里主要看list()这个方法,当调用这个方法的时候,最终效果和上面servlet的效果一样,这里用到了`ModelAndView`。 ### ModelAndView:模型&视图 通常我们的页面都是动态的,客户端看到的页面,基本上都是模板(视图)+数据(数据模型),经过组装之后输出到客户端的。 所以响应客户端的请求,需要指定2个关键的信息:页面,页面中需要的数据。 springmvc中就使用ModelAndView来存放着2个关键的信息,通过`modelAndView.addObject`方法来添加页面中需要用到的数据,通过`modelAndView.setViewName("视图名称")`来设置需要显示的页面。 #### modelAndView.addObject("key","value") > 添加页面中需要用到的数据,效果同:request.setAttribute("key","value"); #### modelAndView.setViewName("视图名称") > 指定需要显示的视图命名,比如jsp地址 ### 小结 如果页面中需要用到一些动态的数据,此时可以使用ModelAndView作为返回值,将动态数据放到ModelAndView中。 ## 5、方式2:直接返回视图名称 当页面不需要用到后端的数据的时候,就只是显示一个页面,此时可以直接将视图的名称作为返回值就可以了,比如 ```java /** * 跳转到新增页面 * * @return */ @RequestMapping("/user/add.do") public String add() { //直接返回视图的名称(页面的路径) return "/WEB-INF/view/user/add.jsp"; } ``` ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/b9ffef11-bc28-495f-bf30-1d29bc8e7691.png) ## 6、方式3:指定视图解析器 ### 存在的问题 大家看下上面2种方式,返回的视图名称,都以`/WEB-INF/view/`开头,以`.jsp`结尾对不对。 如果项目中我们规定所有的视图都符合这种规则,即都放在`/WEB-INF/view/`目录中,都是jsp文件,那么我们可以将视图的名称是不是可以简化一下,怎么做的呢? 具体2个步骤。 ### step1:注册视图解析器 > 在springmvc配置文件中添加下面配置,来指定视图解析器。 > > 这个bean会对视图的名称进行处理,有2个参数需要指定 > > - prefix:视图文件前缀 > > - suffix:视图文件后缀 > > 最终视图的名称 = prefix+controller中指定的viewname+suffix ```xml <!-- 添加视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> ``` ### step2:调整controller中视图的名称 | viewName旧值 | viewName新值 | | --------------------------- | ------------ | | /WEB-INF/view/user/add.jsp | user/add | | /WEB-INF/view/user/list.jsp | user/list | ```java @RequestMapping("/user/add.do") public String add() { //直接返回视图的名称(页面的路径) return "user/add"; } ``` > 此时代码是不是简单多了。 ## 7、SpringMVC实现重定向2种方式 ### 需求 有时候,请求之后,需要做重定向操作,比如发送删除用户信息的请求`/user/del/{用户id}.do`,后端处理成功之后,需重定向到用户列表页面`/user/list.do` 这里就需要用到重定向的操作了,在servlet的中对应代码是 ``` response.sendRedirect(location); ``` springmvc中有好几种实现,这里我们主要掌握2种。 ### 方式1:返回String类型 springmvc中实现重定向比较简单,视图的名称必须需要以`redirect:`开头,比如下面代码,处理删除用户的请求,删除成功之后,重定向到用户列表页面 ```java /** * 删除用户信息,删除成功之后重定向到用户列表页 * * @param userId 用户id * @return */ @GetMapping("/user/del/{userId}.do") public String del(@PathVariable("userId") Long userId, HttpServletRequest request) { //删除用户信息 this.userDtoMap.remove(userId); //重定向到用户列表页面,此时浏览器地址会发生变化,变为http://localhost:8080/chat05/user/list.do return "redirect:/user/list.do"; } ``` ### 方式2:返回ModelAndView类型 如果重定向的时候,我们需要向重定向的页面携带参数,一般我们可以这么做,代码如下: ```java return "redirect:/user/list.do?在这里拼参数"; ``` 比如 ```java return "redirect:/user/list.do?p1=v1&p2=v2"; ``` 如果遇到了这种请求,参数比较少的情况,按照上面拼接是可以的。 springmvc中提供了更简单的方式,代码如下,最终springmv会指定将ModelAndView中添加的数据,拼接到重定向的url中 ```java @GetMapping("/user/del1/{userId}.do") public ModelAndView del1(@PathVariable("userId") Long userId) { //删除用户记录 this.userDtoMap.remove(userId); /** * 重定向到用户列表页面,此时浏览器地址会发生变化, * 变为http://localhost:8080/chat05/user/list.do?p1=v1&p2=v2 */ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("p1", "v1"); modelAndView.addObject("p2", "v2"); modelAndView.setViewName("redirect:/user/list.do"); return modelAndView; } ``` ## 8、案例代码 ### git地址 ```html https://gitee.com/javacode2018/springmvc-series ``` ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/6351a5aa-57b0-467f-b44f-72f6128e32de.png) ### 案例说明 > 案例中实现了用户信息的增删改查,用到了上面讲到的所有技术。 #### 用户列表页 http://localhost:8080/chat05/user/list.do ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/9802bc84-e8ef-4450-bd01-29f0d9d92ff3.png) #### 新增用户页面 http://localhost:8080/chat05/user/add.do ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/df22591a-e6e2-4b73-85d5-2d86c68b9147.png) #### 修改用户信息页面 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/41652c3a-3840-4fb7-884f-ea30548fcc3c.png) #### 删除用户信息 > 删除用户信息之后,会被重定向到用户列表页,案例中列出了2种删除,用来模拟2种重定向的效果。 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/218/6d329279-3b44-4f5b-8ae5-ac40518e527a.png) ## 9、总结 - 响应页面通常有2种方式,第1种返回ModelAndView,这种方式比较适合页面中需要后端传递数据的,第2种方式直接返回视图的名称,这种适合无需传递数据的。 - springmvc容器中配置InternalResourceViewResolver视图解析器,用来简化controller中视图的名称 - 掌握重新的2种方式,重定向的关键点是视图名称要以`redirect:`开头,这样springmvc才知道你需要springmvc来帮你执行重定向操作。 <a style="display:none" target="_blank" href="https://mp.weixin.qq.com/s/_S1DD2JADnXvpexxaBwLLg" style="color:red; font-size:20px; font-weight:bold">继续收门徒,亲手带,月薪 4W 以下的可以来找我</a> ## 最新资料 1. <a href="https://mp.weixin.qq.com/s?__biz=MzkzOTI3Nzc0Mg==&mid=2247484964&idx=2&sn=c81bce2f26015ee0f9632ddc6c67df03&scene=21#wechat_redirect" target="_blank">尚硅谷 Java 学科全套教程(总 207.77GB)</a> 2. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484192&idx=1&sn=505f2faaa4cc911f553850667749bcbb&scene=21#wechat_redirect" target="_blank">2021 最新版 Java 微服务学习线路图 + 视频</a> 3. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484573&idx=1&sn=7f3d83892186c16c57bc0b99f03f1ffd&scene=21#wechat_redirect" target="_blank">阿里技术大佬整理的《Spring 学习笔记.pdf》</a> 4. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484544&idx=2&sn=c1dfe907cfaa5b9ae8e66fc247ccbe84&scene=21#wechat_redirect" target="_blank">阿里大佬的《MySQL 学习笔记高清.pdf》</a> 5. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485167&idx=1&sn=48d75c8e93e748235a3547f34921dfb7&scene=21#wechat_redirect" target="_blank">2021 版 java 高并发常见面试题汇总.pdf</a> 6. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485664&idx=1&sn=435f9f515a8f881642820d7790ad20ce&scene=21#wechat_redirect" target="_blank">Idea 快捷键大全.pdf</a> ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/1/2883e86e-3eff-404a-8943-0066e5e2b454.png)
#custom-toc-container