详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

news2024/12/27 15:34:49

目录

  • 前言
  • 1. 注解用法
    • 1.1 方法参数
    • 1.2 方法
    • 1.3 类
  • 2. 注解场景
    • 2.1 表单参数
    • 2.2 AJAX请求
    • 2.3 文件上传
  • 3. 实战
  • 4. 总结

前言

将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性

可以在方法参数、方法或者类上使用

一般适用这几种场景:

  • 表单处理:通过 @ModelAttribute 将表单数据绑定到模型对象上
  • 预处理逻辑:在请求处理之前执行一些初始化操作,如设置常见模型属性
  • RESTful API:结合 @RequestBody 处理 JSON 数据

对于Java的相关知识推荐阅读:java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)

1. 注解用法

1.1 方法参数

将表单参数(name 和 email)绑定到 User 对象上,并将这个对象作为模型属性传递给视图

后端结合User,对应这个User属性要写全,才能获取到对应属性

@Controller
public class UserController {

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String addUser(@ModelAttribute User user, Model model) {
        // 处理业务逻辑
        model.addAttribute("user", user);
        return "userDetails";
    }
}

前端对应捕捉相关的表单值

<form action="/user" method="post">
    <input type="text" name="name" />
    <input type="text" name="email" />
    <button type="submit">Submit</button>
</form>

1.2 方法

控制器方法上使用 @ModelAttribute 注解,可以在每个请求处理方法调用之前执行一些预处理操作,如初始化模型数据

对应的后端示例如下:

@Controller
public class UserController {

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("message", "Welcome to the user page!");
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getUserForm(Model model) {
        // 模型中已经包含了 "message" 属性
        return "userForm";
    }
}

前端视图如下:

<!-- userForm.jsp -->
<html>
<body>
    <h1>${message}</h1>
    <form action="/user" method="post">
        <input type="text" name="name" />
        <input type="text" name="email" />
        <button type="submit">Submit</button>
    </form>
</body>
</html>

对应每次请求都会在控制器方法调用之前添加一个名为 "message" 的模型属性

1.3 类

在类上使用 @ModelAttribute 注解,可以为所有该类的请求处理方法添加共同的模型属性

对应后端写法如下:

@Controller
@SessionAttributes("user")
public class UserController {

    @ModelAttribute("user")
    public User createUser() {
        return new User();
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getUserForm(@ModelAttribute("user") User user) {
        return "userForm";
    }

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String submitUser(@ModelAttribute("user") User user) {
        // 处理业务逻辑
        return "userDetails";
    }
}

2. 注解场景

与上面的第一章有些重复,不过容易理解

2.1 表单参数

表单参数:处理来自前端 HTML 表单的数据,将表单字段绑定到 Java 对象上
(其Demo对应此章的1.1
在这里插入图片描述

也可通过编辑用户信息,绑定到相关的模型对象

@Controller
public class UserController {

    @RequestMapping(value = "/user/edit", method = RequestMethod.GET)
    public String editUser(@ModelAttribute User user, @RequestParam("userId") Long userId, Model model) {
        // 通过 userId 获取用户信息并填充到 user 对象
        user = userService.findById(userId);
        model.addAttribute("user", user);
        return "editUserForm";
    }
}

2.2 AJAX请求

配合前端进行交互,此处写一个示例的Demo

使用 JavaScript(例如 jQuery 或者原生的 XMLHttpRequest)发送异步请求,后端通过 @RequestBody 结合 @ModelAttribute 解析 JSON 数据

$.ajax({
    url: '/user',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ name: 'John', email: 'john@example.com' }),
    success: function(response) {
        console.log(response);
    }
});

对应后端如下:

@Controller
public class UserController {

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    @ResponseBody
    public User addUser(@RequestBody @ModelAttribute User user) {
        // 处理业务逻辑
        return user;
    }
}

2.3 文件上传

前端使用 <form> 标签并设置 enctype="multipart/form-data",后端通过 @ModelAttribute 绑定文件数据

前端:

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">Upload</button>
</form>

后端:

@Controller
public class FileUploadController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {
        // 处理文件上传逻辑
        return "fileUploadSuccess";
    }
}

3. 实战

通过实战前端交互加深印象

此处使用Vue3 + Java

对应的函数调用如下:

options中添加了file的对应属性,但是后续需要将id传输给后端
在这里插入图片描述

对应的JS如下:

// 上传文件
export const updateFile = (data: any) => {
  const formData = new FormData();
  formData.append('file', data.file);
  formData.append('appointmentId', data.id.toString());

  return request.upload({
    url: '/dangerous/appointment-commission/appointment-file/upload',
    data: formData
  });
}

其后端的写法如下:

@PostMapping("/appointment-file/upload")
@Operation(summary = "上传文件", description = "模式一:后端上传文件")
public CommonResult<String> uploadFile(@ModelAttribute FileUploadReqVO uploadReqVO,@RequestParam("appointmentId") Long appointmentId) throws Exception {
    MultipartFile file = uploadReqVO.getFile();
    String path = uploadReqVO.getPath();
    return success(appointmentCommissionService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()),appointmentId));
}

4. 总结

  • @RequestBody:数据来自请求体,通常是 JSON 格式
@Controller
public class UserController {

    @RequestMapping(value = "/api/user", method = RequestMethod.POST)
    @ResponseBody
    public User addUser(@RequestBody User user) {
        // 处理 JSON 请求体
        return user;
    }
}
  • @ModelAttribute:数据来自 URL 查询参数、表单参数,或其他请求参数
@Controller
public class UserController {

    @RequestMapping(value = "/form/user", method = RequestMethod.POST)
    public String addUser(@ModelAttribute User user) {
        // 处理表单参数
        return "userDetails";
    }
}

其他注解详情如下:

注解说明
@ModelAttribute适用于将多个请求参数绑定到复杂对象,或在处理请求之前初始化模型数据
@RequestParam适用于获取单个或少量请求参数
@RequestBody适用于处理 JSON 格式的请求体数据
@PathVariable适用于从 RESTful 风格的 URL 中提取路径变量
@RequestHeader适用于访问 HTTP 请求头信息
@CookieValue适用于从请求中获取特定的 Cookie 值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1855311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图形编辑器基于Paper.js教程03:认识Paper.js中的所有类

先来认一下Paper的资源对象&#xff0c;小弟有哪些&#xff0c;有个整体的认识。认个脸。 在Paper.js的 官方文档中类大致有如下这些&#xff1a; 基类&#xff1a; ProjectViewItemPointToolSizeSegmentRectangleCurveCurveLocationMatrixColorStyleTweenToolEventGradient…

用于射频功率应用的氮化铝电阻元件

EAK推出了新的厚膜氮化铝 &#xff08;AlN&#xff09; 电阻器和端接系列&#xff0c;以补充公司现有的产品。传统上&#xff0c;射频功率电阻元件采用氧化铍&#xff08;BeO&#xff09;陶瓷材料作为陶瓷基板;然而&#xff0c;由于国际上要求从产品中去除BeO的压力&#xff0c…

26.3 Django路由层

1. 路由作用 在Django中, URL配置(通常称为URLconf)是定义网站结构的基础, 它充当着Django所支撑网站的目录. URLconf是一个映射表, 用于将URL模式(patterns)映射到Python的视图函数或类视图上. 这种映射机制是Django处理HTTP请求的基础, 它决定了当客户端发送请求时, Django如…

RabbitMQ实践——临时队列

临时队列是一种自动删除队列。当这个队列被创建后&#xff0c;如果没有消费者监听&#xff0c;则会一直存在&#xff0c;还可以不断向其发布消息。但是一旦的消费者开始监听&#xff0c;然后断开监听后&#xff0c;它就会被自动删除。 新建自动删除队列 我们创建一个名字叫qu…

MM-LLM:CogVLM解读

在图文多模态模型中&#xff0c;范式是图像的编码器、文本编码器、模态融合器。也就是不同模态特征抽取加模态对齐。 这部分可以看李沐的精讲 在大模型里的范式在也是如此&#xff0c;目前的工作大部分都专注于怎么拉齐不同模态。 该论文的动机&#xff08;背景&#xff09;&…

Bev系列算法总结

1. LSS-Based 1.1 BevDet 通过Lift splat 对于2d 特征中的每个pixel(特征点)估计一个3d的深度分布,这样就可以将2d点投影到3d空间上。这样就可以拿到UVD个3d特征点,然后通过voxel pooling 对高度方向拍平, 这样就得到Bev空间的特征图。然后再通过Bev encoder以及任务头。 …

vue3-openlayers 使用tianditu,wmts和xyz等source加载天地图切片服务

本篇介绍一下使用vue3-openlayers加载天地图切片&#xff0c;三种方法&#xff1a; 使用tianditu&#xff08;ol-source-tianditu内部实现其实用的wmts&#xff09;使用wmts&#xff08;ol-source-wmts&#xff09;使用xyz&#xff08;ol-source-xyz&#xff09; 1 需求 vue…

ArkTS开发系列之导航 (2.6 图形)

上篇回顾&#xff1a;ArkTS开发系列之导航 (2.5.2 页面组件导航&#xff09; 本篇内容&#xff1a; 显示图片、自定义图形和画布自定义图形的学习使用 一、知识储备 1. 图片组件&#xff08;Image&#xff09; 可以展示jpg 、png 、svg 、gif等各格式的网络和本地资源文件图…

潜艇伟伟迷杂交版植物大战僵尸2024最新免费安卓+ios苹果+iPad分享

嗨&#xff0c;亲爱的游戏迷们&#xff01;今天我要给你们种草一个超有趣的游戏——植物大战僵尸杂交版。这款游戏不仅继承了原有经典游戏的核心玩法&#xff0c;还加入了许多创新元素&#xff0c;让玩家能够体验到前所未有的乐趣。快来跟随我一起探索这个神奇的世界吧&#xf…

自然语言处理领域的明星项目推荐:Hugging Face Transformers

在当今人工智能与大数据飞速发展的时代&#xff0c;自然语言处理&#xff08;NLP&#xff09;已成为推动科技进步的重要力量。而在NLP领域&#xff0c;Hugging Face Transformers无疑是一个备受瞩目的开源项目。本文将从项目介绍、代码解释以及技术特点等角度&#xff0c;为您深…

线程封装,互斥

文章目录 线程封装线程互斥加锁、解锁认识接口解决问题理解锁 线程封装 C/C代码混编引起的问题 此处pthread_create函数要求传入参数为void * func(void * )类型,按理来说ThreadRoutine满足,但是 这是在内类完成封装,所以ThreadRoutine函数实际是两个参数,第一个参数Thread* …

Python 围棋

效果图 完整代码 源码地址&#xff1a;Python 围棋 # 使用Python内置GUI模块tkinter from tkinter import * # ttk覆盖tkinter部分对象&#xff0c;ttk对tkinter进行了优化 from tkinter.ttk import * # 深拷贝时需要用到copy模块 import copy import tkinter.me…

高纯PFA容量瓶PFA试剂瓶在半导体材料的应用

在半导体生产过程中&#xff0c;为避免金属污染对硅器件性能造成不利影响&#xff0c;碳化硅产业链不同阶段产品&#xff08;如衬底、外延、芯片、器件&#xff09;表面的痕量杂质元素浓度表征至关重要。 在实验人员使用质谱法高精度检测第三代半导体碳化硅材料的痕量杂质浓度…

Linux - 探秘 Linux 的 /proc/sys/vm 常见核心配置

文章目录 PreLinux 的 /proc/sys/vm 简述什么是 /proc/sys/vm&#xff1f;主要的配置文件及其用途参数调整对系统的影响dirty_background_ratio 和 dirty_ratioswappinessovercommit_memory 和 overcommit_ratiomin_free_kbytes 实例与使用建议调整 swappiness设置 min_free_kb…

2024.6.23刷题记录

目录 一、P1102 A-B 数对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 1.hash表-一次遍历 2.双指针&#xff08;同向&#xff0c;可以算滑动窗口&#xff09;-排序 二、P8667 [蓝桥杯 2018 省 B] 递增三元组 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 1.排序指针 2…

C++ | Leetcode C++题解之第187题重复的DNA序列

题目&#xff1a; 题解&#xff1a; class Solution {const int L 10;unordered_map<char, int> bin {{A, 0}, {C, 1}, {G, 2}, {T, 3}}; public:vector<string> findRepeatedDnaSequences(string s) {vector<string> ans;int n s.length();if (n < L…

《AI旋律:创意产业的重塑与共生》

AI乐章&#xff1a;技术革命下的创意产业新生态 在数字化浪潮的推动下&#xff0c;音乐创作领域迎来了前所未有的变革——AI音乐大模型的横空出世&#xff0c;犹如一颗石子投入平静的湖面&#xff0c;激起了层层涟漪。这些模型以令人难以置信的速度和多样性&#xff0c;将音乐…

WinForm 2048

WinForm 2048 是一个基于 Windows 窗体应用程序&#xff08;WinForms&#xff09;实现的经典益智游戏——2048。这个游戏通过简单的滑动或点击操作&#xff0c;将相同数字的方块合并&#xff0c;以生成更大的数字方块&#xff0c;最终目标是创造出一个数字为 2048 的方块。 游…

C++ | Leetcode C++题解之第188题买卖股票的最佳时机IV

题目&#xff1a; 题解&#xff1a; class Solution { public:int maxProfit(int k, vector<int>& prices) {if (prices.empty()) {return 0;}int n prices.size();k min(k, n / 2);vector<int> buy(k 1);vector<int> sell(k 1);buy[0] -prices[0]…

Ubuntu 之Glade图形化设计器

演示环境说明&#xff1a;本机使用Windows 11 家庭版本搭载 Ubuntu 22.04.4 LTS 子系统&#xff0c;同时并安装Ubuntu桌面虚拟化软件XLaunch。 如果没有搭建好上述问题&#xff0c;请参考&#xff1a;windows11子系统Ubuntu 22.04.4子安装图形化界面 Glade是什么&#xff1f;…