Java-Spring入门指南(十五)SpringMVC注解开发

Java-Spring入门指南(十五)SpringMVC注解开发


前言

  • 在上一篇博客中,我们通过XML配置完成了SpringMVC项目搭建,手动配置了处理器映射器、适配器等组件,虽能直观理解流程,但配置代码冗余、开发效率较低。
  • 实际开发中,注解开发 是主流方案------它能大幅减少XML配置,通过@Controller@RequestMapping等注解快速定义控制器与请求映射,还能简化参数接收、数据传递逻辑。
  • 本文将基于上一篇的Maven+IDEA+Tomcat 11环境,聚焦SpringMVC注解开发的核心:从项目结构调整,到Controller注解、参数接收、视图交互的实战,帮你掌握更高效的开发模式。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482


一、调整Java Web环境

由于基础环境(Maven、Tomcat 11、核心依赖)已在上一篇配置完成,本文仅需做2处微调,无需重复搭建:

上一篇博客地址https://blog.csdn.net/2402_83322742/article/details/152268810?spm=1001.2014.3001.5501

1. 调整项目结构

相比上一篇的"仅Controller层",注解开发需新增pojo层存储实体类(如接收表单数据的User),最终结构如下:

复制代码
springMVC
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com.niit  // 注意包名统一,避免扫描不到
│   │   │       ├── controller  // 控制器层
│   │   │       │   ├── HelloController.java
│   │   │       │   └── IndexController.java
│   │   │       └── pojo       // 实体类层(新增)
│   │   │           └── User.java
│   │   └── resources
│   │       └── springmvc.xml  // SpringMVC核心配置
│   └── test
├── web
│   ├── WEB-INF
│   │   ├── jsp               // 视图层
│   │   │   └── hello.jsp
│   │   └── web.xml           // 前端控制器配置(复用上一篇)
│   └── index.jsp             // 表单页面(新增)
└── pom.xml                   // 依赖(复用上一篇,无需新增)

2. 确认依赖完整性

上一篇已导入spring-webmvcservlet-apilombok等依赖,其中lombok是本次实体类开发的关键(减少getter/setter代码),无需额外添加。

java 复制代码
<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>6.2.10</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- AspectJ织入依赖:支持AOP功能的核心依赖 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.38</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

二、注解开发核心代码实现

注解开发的核心是"用注解替代XML配置",以下按"实体类→Controller→配置→视图"的顺序逐步实现,每段代码均附核心逻辑解释。

1. 实体类:User.java(接收表单数据)

用于封装前端表单的"用户名""密码"参数,通过Lombok注解简化代码,无需手动编写gettersettertoString

java 复制代码
package com.niit.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

// Lombok四大注解,替代手动编写的getter/setter/构造方法/toString
@Data
@ToString  // 自动生成toString(),方便打印实体类数据
@AllArgsConstructor  // 全参构造方法
@NoArgsConstructor   // 无参构造方法(SpringMVC接收参数时必须)
public class User {
    // 注意:属性名必须与前端表单<input>的name属性一致!
    private String username;  // 对应前端name="username"
    private String password;  // 对应前端name="password"(修正原代码的passewd拼写错误)
}

代码核心逻辑解释

  • @Data:Lombok核心注解,自动生成所有属性的getter()setter()equals()hashCode()等方法。
  • 属性名与前端表单的name必须一致:例如前端<input name="username">,后端实体类属性必须是username,否则SpringMVC无法自动封装参数。

2. Controller层

Controller是注解开发的核心,通过@Controller(返回视图)或@RestController(返回字符串/JSON)定义控制器,用@RequestMapping绑定请求路径。

(1)HelloController.java

用于演示"跳过视图解析器,直接返回字符串"(适合接口开发),需注意@RestController的特殊作用。

java 复制代码
package com.niit.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// @RestController = @Controller + @ResponseBody
// 作用:1. 标记此类为控制器;2. 方法返回值直接转为字符串/JSON,不经过视图解析器
@RestController
public class HelloController {

    // @RequestMapping("/hello"):绑定请求路径,访问http://localhost:8080/hello会触发此方法
    @RequestMapping("/hello")
    public String hello() {
        // 返回字符串,直接在页面显示,不会去找/WEB-INF/jsp/hello.jsp
        return "hello springMVC 002";
    }
}

(2)IndexController.java(@Controller+参数接收示例)

用于演示"返回视图"和"参数接收"的两种核心方式:@RequestParam单个接收、实体类批量接收,是实际开发中最常用的场景。

java 复制代码
package com.niit.controller;

import com.niit.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// @Controller:标记此类为控制器,方法返回值默认是"视图名"(需经过视图解析器)
@Controller
public class IndexController {

    // 1. 基础用法:返回视图+传递数据
    // @RequestMapping(path = {"index"}):path支持数组,可绑定多个路径(如同时支持/index和/index1)
    @RequestMapping(path = {"index"})
    public String index(Model model) {
        // Model:用于向视图传递数据,类似上一篇的ModelAndView
        model.addAttribute("msg", "Hello World(来自注解开发)");
        // 返回"视图名",视图解析器会拼接为/WEB-INF/jsp/hello.jsp
        return "hello";
    }

    // 2. 参数接收方式1:@RequestParam单个接收(适合参数少的场景)
    // @RequestParam("username"):将前端name="username"的参数,赋值给后端变量name
    @RequestMapping("/login")
    public String login(Model model, 
                        @RequestParam("username") String name, 
                        @RequestParam("password") String word) {
        // 将接收的参数传递给视图
        model.addAttribute("msg", "用户名:" + name + ",密码:" + word);
        return "hello"; // 跳转到hello.jsp显示数据
    }

    // 3. 参数接收方式2:实体类批量接收(适合参数多的场景,如10个input)
    // 原理:SpringMVC自动将前端参数按"name属性"匹配实体类的"属性名",自动封装为User对象
    @RequestMapping("/login1")
    public String login1(Model model, User user) {
        // 通过User的toString()打印数据(Lombok自动生成)
        model.addAttribute("msg", "用户信息:" + user.toString());
        return "hello";
    }
}

代码核心逻辑解释

  • Model:替代上一篇的ModelAndView,专门用于"向视图传递数据",addAttribute("key", value)后,视图可通过${key}获取。
  • @RequestParam:当"前端参数名"与"后端变量名"不一致时必须用(如前端username,后端name);若一致,可省略此注解。
  • 实体类接收的优势:当表单有10个参数时,无需写10个@RequestParam,只需传一个User对象,SpringMVC自动封装,极大简化代码。

3. SpringMVC配置:springmvc.xml(注解核心配置)

相比上一篇的"手动配置映射器、适配器",注解开发只需2行核心配置,即可替代所有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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           https://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc
                           https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 1. 组件扫描:扫描com.niit包下所有带@Controller、@Service等注解的类,自动注册为Spring Bean -->
    <!-- 注意:base-package必须写对,否则@Controller注解不生效 -->
    <context:component-scan base-package="com.niit"/>

    <!-- 2. 开启MVC注解驱动:自动配置处理器映射器、处理器适配器 -->
    <!-- 替代上一篇手动配置的BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter -->
    <mvc:annotation-driven/>

    <!-- 3. 视图解析器:复用上一篇的配置,无变化 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 视图前缀 -->
        <property name="suffix" value=".jsp"/>          <!-- 视图后缀 -->
    </bean>
</beans>

代码核心逻辑解释

  • <context:component-scan>:是注解生效的前提,若不配置,Spring无法识别@Controller注解,请求会404。
  • <mvc:annotation-driven>:SpringMVC的"智能配置",自动适配注解开发所需的组件,无需再手动写映射器、适配器的XML配置,减少冗余。

4. 视图层:JSP页面(交互展示)

视图层包含2个页面:index.jsp(表单提交页面)和hello.jsp(数据展示页面),均为前端交互的核心。

(1)index.jsp(表单页面,位于web根目录)

用于提交用户信息,对应IndexController/login/login1方法。

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SpringMVC注解开发-登录</title>
    <style>
        form { margin: 20px; }
        input { margin: 5px 0; }
    </style>
</head>
<body>
    <h3>1. 测试@RequestParam参数接收</h3>
    <!-- action="/login":提交到IndexController的/login方法,method="get"(也可改为post) -->
    <form method="get" action="/login">
        用户名:<input type="text" name="username" required><br>
        密码:<input type="password" name="password" required><br>
        <input type="submit" value="登录(单个参数接收)">
    </form>

    <h3>2. 测试实体类参数接收</h3>
    <!-- action="/login1":提交到IndexController的/login1方法 -->
    <form method="get" action="/login1">
        用户名:<input type="text" name="username" required><br>
        密码:<input type="password" name="password" required><br>
        <input type="submit" value="登录(实体类接收)">
    </form>
</body>
</html>

(2)hello.jsp(数据展示页面,位于WEB-INF/jsp)

用于展示Controller传递的msg数据,复用上一篇的页面逻辑,无本质变化。

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>数据展示</title>
    <style>
        h2 { color: #2c3e50; margin: 20px; }
    </style>
</head>
<body>
    <!-- ${msg}:获取Controller通过Model传递的数据 -->
    <h2>${msg}</h2>
</body>
</html>

三、项目运行与功能测试

配置完成后,启动Tomcat 11,按以下步骤测试所有功能,验证注解开发是否生效。

1. 运行前检查

  • 确认Tomcat配置:应用上下文改为/(和上一篇一致),URL无需修改,启动端口默认8080。
  • 确认组件扫描包名:springmvc.xmlbase-package="com.niit"必须正确,若写成com.niit.controller,则pojo层的User不影响(但建议扫描整个父包)。
  • 确认实体类属性名:Userusernamepassword必须与前端表单name一致,避免参数接收不到。

2. 分功能测试

启动Tomcat后,访问http://localhost:8080进入index.jsp,按以下3个场景测试:

测试场景 访问路径/操作 预期结果
@RestController返回字符串 直接访问http://localhost:8080/hello 页面显示"hello springMVC 002",无视图跳转
@RequestParam参数接收 在index.jsp填写表单,点击"登录(单个参数接收)" 跳转到hello.jsp,显示"用户名:xxx,密码:xxx"
实体类批量接收 在index.jsp填写表单,点击"登录(实体类接收)" 跳转到hello.jsp,显示"用户信息:User(username=xxx, password=xxx)"
Model传递数据 访问http://localhost:8080/index 跳转到hello.jsp,显示"Hello World(来自注解开发)"




我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的Java-Spring入门指南知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13040333.html?spm=1001.2014.3001.5482

|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |

相关推荐
小满、3 小时前
什么是Maven?关于 Maven 的坐标、依赖管理与 Web 项目构建
java·maven
半旧夜夏3 小时前
【设计模式】核心设计模式实战
java·spring boot·设计模式
半旧夜夏4 小时前
【Spring】AOP的核心原理配方
java·spring
qiuiuiu4134 小时前
CPrimer Plus第十六章C预处理器和C库总结2-qsort函数
java·c语言·算法
IT学长编程4 小时前
计算机毕设选题 基于SpringBoot的书店管理系统的设计与实现 网上书店系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·前后端分离·网上书店系统·书店管理系统
张较瘦_4 小时前
应用型本科计算机类专业毕业设计与论文选题指南
java·开发语言·课程设计
IT学长编程4 小时前
计算机毕设选题 基于SpringBoot的房产租赁管理系统 房屋租赁系统 前后端分离 Java毕设项目 毕业设计选题 【附源码+文档报告+安装调试】
java·spring boot·毕业设计·课程设计·房屋租赁系统·房产租赁系统·文档报告
木易 士心6 小时前
MPAndroidChart 用法解析和性能优化 - Kotlin & Java 双版本
android·java·kotlin