2025年SpringMVC返回视图常见的 5 种方式,你会几种?- SpringMVC系列

SpringMVC返回视图常见的 5 种方式,你会几种?- SpringMVC系列当 http 请求被自定义的 controller 处理时 如何指定响应的页面呢 这个就是我们本文需要讨论的问题 在 controller 中响应页面有很多种方式 稍后我们会一一介绍 大家需要掌握每种方式的用法以及这些方式之间的区别 以后能够灵活使用 本文用到的页面都以 jsp 为例

大家好,我是讯享网,很高兴认识大家。

当 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:转向

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 实现用户列表功能,如下图

c31826e69381d24fa50f354a536a76bf.png
讯享网

如何实现?

我们先来看一下如果用 servlet 是如何实现的,代码如下:

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

讯享网<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 实现

@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:直接返回视图名称

当页面不需要用到后端的数据的时候,就只是显示一个页面,此时可以直接将视图的名称作为返回值就可以了,比如

讯享网/ * 跳转到新增页面 * * @return */ @RequestMapping("/user/add.do") public String add() { //直接返回视图的名称(页面的路径) return "/WEB-INF/view/user/add.jsp"; } 

复制

d02e6b4c33821b2817a61ef1599016b0.png

6、方式 3:指定视图解析器

存在的问题

大家看下上面 2 种方式,返回的视图名称,都以/WEB-INF/view/开头,以.jsp结尾对不对。

如果项目中我们规定所有的视图都符合这种规则,即都放在/WEB-INF/view/目录中,都是 jsp 文件,那么我们可以将视图的名称是不是可以简化一下,怎么做的呢?

具体 2 个步骤。

step1:注册视图解析器

在 springmvc 配置文件中添加下面配置,来指定视图解析器。 这个 bean 会对视图的名称进行处理,有 2 个参数需要指定

  • prefix:视图文件前缀
  • suffix:视图文件后缀

最终视图的名称 = prefix+controller 中指定的 viewname+suffix

<!-- 添加视图解析器 --> <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

讯享网@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:开头,比如下面代码,处理删除用户的请求,删除成功之后,重定向到用户列表页面

讯享网/ * 删除用户信息,删除成功之后重定向到用户列表页 * * @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 类型

如果重定向的时候,我们需要向重定向的页面携带参数,一般我们可以这么做,代码如下:

return "redirect:/user/list.do?在这里拼参数"; 

复制

比如

讯享网return "redirect:/user/list.do?p1=v1&p2=v2"; 

复制

如果遇到了这种请求,参数比较少的情况,按照上面拼接是可以的。

springmvc 中提供了更简单的方式,代码如下,最终 springmv 会指定将 ModelAndView 中添加的数据,拼接到重定向的 url 中

@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 地址

讯享网https://gitee.com/javacode2018/springmvc-series 

复制

c8c4a83fe1f19d47d3e43bcca254acc6.png

案例说明

案例中实现了用户信息的增删改查,用到了上面讲到的所有技术。

用户列表页

http://localhost:8080/chat05/user/list.do

c31826e69381d24fa50f354a536a76bf.png

新增用户页面

http://localhost:8080/chat05/user/add.do

7d9c30e5c70855e83007d6651b63a2eb.png

修改用户信息页面

2063825ae26e0c5d2ea9d2d97b961487.png

删除用户信息

删除用户信息之后,会被重定向到用户列表页,案例中列出了 2 种删除,用来模拟 2 种重定向的效果。

833d591886cf06630e68f7a19b2a9b62.png

9、总结

  • 响应页面通常有 2 种方式,第 1 种返回 ModelAndView,这种方式比较适合页面中需要后端传递数据的,第 2 种方式直接返回视图的名称,这种适合无需传递数据的。
  • springmvc 容器中配置 InternalResourceViewResolver 视图解析器,用来简化 controller 中视图的名称
  • 掌握重新的 2 种方式,重定向的关键点是视图名称要以redirect:开头,这样 springmvc 才知道你需要 springmvc 来帮你执行重定向操作。
小讯
上一篇 2025-03-14 13:29
下一篇 2025-02-20 19:44

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/118252.html