SpringBoot--@ModelAttribute--使用/实例

原文网址:SpringBoot--@ModelAttribute--使用/实例_IT利刃出鞘的博客-CSDN博客

简介

说明

        本文介绍@ModelAttribute注解的用法。

作用

        @ModelAttribute可以用在方法参数上或方法上,它的作用主要是当注解在方法参数上时会将注解的参数对象添加到Model中。若被@ModelAttribute注释的方法不是请求方法,则此方法会在此controller每个方法执行前被执行。

使用场景

        当@ModelAttribute注解用于方法时,与其处于同一个处理类的所有请求方法执行前都会执行一次此方法,这可能并不是我们想要的,我们使用更多的是将其应用在请求方法的参数上。

        @ModelAttribute的一部分功能与@RequestParam注解是一致的,只不过@RequestParam用于绑定单个参数值,而@ModelAttribute注解可以绑定所有名称匹配的,此外它自动将绑定后的数据添加到模型中。

用法1:用在方法上获得任意实体

代码

实体类

package com.example.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;
    private String name;
    private Integer age;
}

 控制器

package com.example.controller;

import com.example.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("/test1")
    public User test1(User user) {
        System.out.println("HelloController.test1");
        return user;
    }
}

@ModelAttribute类

package com.example.advice;

import com.example.entity.User;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class GlobalControllerAdvice {
    @ModelAttribute
    public User authenticationUser(HttpServletRequest httpServletRequest, User user) {
        System.out.println("GlobalControllerAdvice.authenticationUser");
        System.out.println("URL:" + httpServletRequest.getRequestURL());
        if (user.getName() != null && "Tony".equals(user.getName())) {
            user.setAge(20);
            return user;
        }
        throw new RuntimeException("用户名错误");
    }
}

测试

postman访问:http://localhost:8080/hello/test1?name=Tony 

后端结果

GlobalControllerAdvice.authenticationUser
URL:http://localhost:8080/hello/test1
HelloController.test1

postman结果

{
    "id": null,
    "name": "Tony",
    "age": 20
}

 postman访问:http://localhost:8080/hello/test1?name=Stark 

后端结果

GlobalControllerAdvice.authenticationUser
URL:http://localhost:8080/hello/test1
2020-09-05 18:17:41.669 ERROR 4240 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: 用户名错误] with root cause

java.lang.RuntimeException: 用户名错误
	at com.example.advice.GlobalControllerAdvice.authenticationUser(GlobalControllerAdvice.java:19) ~[classes/:na]

postman结果

HTTP Status 500 – Internal Server Error

用法2:用在参数上获得实体

        @ModelAttribute注释方法的一个参数表示应从模型model中取得。若在model中未找到,那么这个参数将先被实例化后加入到model中。若在model中找到,则请求参数名称和model属性字段若相匹配就会自动填充。这个机制对于表单提交数据绑定到对象属性上很有效。

代码

package com.example.controller;

import com.example.entity.User;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
//    方法1:通过返回值的方式默认地将添加一个属性
//      属性名没有被显式指定的时:框架将根据属性的类型给予一个默认名称
//      例如:本例返回一个 User 类型的对象,则默认的属性名为"user"
//      你可以通过设置 @ModelAttribute 注解的值来改变默认值  @ModelAttribute("myUser")
    @ModelAttribute("user")
    public User addUser(String name) {
        System.out.println("addUser without model");
        User user = new User();
        user.setName(name);
        return user;
    }

    @RequestMapping("/test")
    public User test(@ModelAttribute("user")User user) {
        user.setAge(22);
        return user;
    }
}

测试

访问:http://localhost:8080/test?name=Tony

响应:

{
    "id": null,
    "name": "Tony",
    "age": 22
}

用法3:用在方法上设置属性

        有两种类型的@ModelAttribute方法。一种是:只加入一个属性,用方法的返回类型隐含表示。另一种是:方法接受一个Model类型的参数,这个model可以加入任意多个model属性。

后端

package com.example.controller;

import com.example.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController {
//    方法1:通过返回值的方式默认地将添加一个属性
//      属性名没有被显式指定的时:框架将根据属性的类型给予一个默认名称
//      例如:本例返回一个 User 类型的对象,则默认的属性名为"user"
//      你可以通过设置 @ModelAttribute 注解的值来改变默认值  @ModelAttribute("myUser")
    @ModelAttribute
    public User addUser(String name) {
        System.out.println("addUser without model");
        User user = new User();
        user.setName(name);
        return user;
    }

    // 方法2:方法接收一个 Model 对象,然后可以向其中添加任意数量的属性
    @ModelAttribute
    public void addUser(String name, Model model) {
        System.out.println("addUser with model");
        model.addAttribute("name", "Tony");
        model.addAttribute("age", 20);
    }

    @RequestMapping("/test")
    public ModelAndView test() {
        return new ModelAndView("hello");
    }
}

前端

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
账户名称:${account.name}<br/>
年龄:${account.age}<br/>
number:${number}<br/>
other:${other}<br/>
</body>
</html>

用法4:@ModelAttribute和@RequestMapping同时注释一个方法

后端 

@Controller
@RequestMapping(value="/test")
public class TestController {

    @RequestMapping(value = "/helloWorld")
    @ModelAttribute("attributeName")
    public String helloWorld() {
       return "hi";
    }
}

        这时这个方法的返回值并不是表示一个视图名称,而是model属性的值,视图名称由RequestToViewNameTranslator根据请求"/helloWorld"转换为helloWorld。Model属性名称由@ModelAttribute(value="")指定,相当于在request中封装了key=attributeName,value=hi。

前端Jsp页面

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>helloWorld</title>
  </head>
  
  <body>
      The attributeValue is:  ${attributeName}
  </body>
</html>

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/125528394