SpringMVC Controller返回值技巧:ModelAndView vs String的实战对比

前言

SpringMVC的相关小细节较多,这个博客主要针对控制层(Controller)中控制器方法的返回值为ModelAndView类型和返回值为String类型区别做出比较和案例实现

第一步:创建web项目,添加依赖,配置web.xml

添加依赖

pom.xml:

XML 复制代码
<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>


  <build>
    <finalName>springmvc1008</finalName>
    <plugins>

      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.3.14.v20161028</version>
      </plugin>

      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
          <server>tomcat7</server>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

添加依赖包括:juint单元测试,springmvc依赖,servlet依赖

添加两个插件:jetty服务器插件,tomcat服务器插件

注意:两个插件的目的是为了我们可以在maven项目中模拟本地服务器(tomcat或jetty)启动web项目

配置web.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app
        version="4.0"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        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">
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.cx</url-pattern>
  </servlet-mapping>
</web-app>
  • 注意,如果不配置 <init-param>的话,那么springmvc会去WEB-INF/路径下去查找"你的servletname"-servlet.xml的配置文件,所以一般都会配置局部初始化参数,告诉spring配置文件的路径和名称.
  • 基于代码可读性的要求,尽量将请求url定义为*.do 或者*.action,以便区分前台请求和静态资源.(我这里设置为cx,这意味着访问请求时,需要带上后缀.cx,例如访问/login,需要在地址栏书写/login.cx)

spring.xml

XML 复制代码
<?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:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util-4.1.xsd">
    <!-- 默认扫描的包路径 -->
    <context:component-scan base-package="com.csx"/>
    <!-- 添加注解驱动 -->
    <mvc:annotation-driven/>

    <!--处理器映射器-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
    <!--处理器适配器-->
<!--    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>-->

    <!--视图解析器-->
    <!-- 定义跳转的文件的前后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp"/>


<!--    <bean name="/hello" class="com.csx.HelloController" />-->

</beans>	
	

基于注解开发的SpringMVC只需要配置默认扫描的包路径和添加注解驱动以及配置视图解析器即可

第二步:配置controller

在相应的控制器类中要添加@Controller注解,它本意和@Component 一致, 只不过带有特殊含义.

接下来进行案例分析:

登录页面

login.jsp

html 复制代码
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2024/10/8
  Time: 15:49
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/login.cx" method="post">
    用户名: <input type="text" name="user_name"> <br/>
    密码: <input type="password" name="password"> <br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

因为在web.xml中配置了后缀,所以这里的form表单中的action属性的url值,需要带上.cx后缀

登录案例(ModelAndView)

java 复制代码
@Controller
public class UserController {
    @RequestMapping("/login")
    public ModelAndView login(String user_name,String password){
        ModelAndView mv =new ModelAndView();
        if ("root".equals(user_name) && "123".equals(password)){
            mv.addObject("username",user_name);
            mv.setViewName("main");
        }else {
            mv.setViewName("login");
        }
        return mv;
    }
}
  • 将表单项的name属性值和控制器方法的形参名保持一致,就可以接受页面传递过来的参数。

  • @RequestMapping注解可以接受get和post的请求,如果想要设置接收指定类型,有两种方式

    • @GetMapping 和@PostMapping

    • @RequestMapping(value = "/login",method = RequestMethod.POST)

    • @RequestMapping(value = "/login",method = RequestMethod.GET)

  • @Controller注解,它本意和@Component 一致, 只不过带有特殊含义.

  • addObject方法可以向request域中存取数据,并且return ModelAndView对象默认转发请求(forward)

  • setViewName方法可以设置要跳转的视图名

登录案例(String)

java 复制代码
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(User user , HttpSession session){
        if ("admin".equals(user.getUser_name()) &&"123".equals(user.getPassword())){
            session.setAttribute("user",user);
            return "main";
        }else {
            return "login";
        }
    }
  • controller控制器的参数可以是任意类型,包括了对象和HttpSession类型。
  • 如果是对象类型接收前端传入的参数,需要参数名与对象的属性名一一对应。

比较分析

返回值为ModelAndView

其中,addObject用来存值,setViewName用来指定页面视图名称,视图解析器会添加上前缀和后缀,最后返回ModelAndView对象即可.

返回值为String

  • 只需将跳转的页面当做返回值即可.如果需要传递数据,可以在参数中使用Model的addAttribute方法.
  • 无论返回值时ModelAndView还是String,参数绑定机制都一样,即:
  • 只要表单或请求中的参数与方法参数一致,或者与参数对象的属性一致,即可自动绑定.
相关推荐
uppp»44 分钟前
深入理解 Java 反射机制:获取类信息与动态操作
java·开发语言
玩电脑的辣条哥3 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452183 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52353 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
Moon.93 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
垚垚 Securify 前沿站3 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
m0_748256144 小时前
SpringBoot
java·spring boot·后端
阿华的代码王国5 小时前
【从0做项目】Java搜索引擎(3)
java·搜索引擎·项目
Mr.朱鹏5 小时前
针对Feign客户端请求体参数处理问题
java·jvm·spring boot·spring·spring cloud·maven·intellij-idea
ll7788115 小时前
LeetCode每日精进:20.有效的括号
c语言·开发语言·算法·leetcode·职场和发展