广告位联系
返回顶部

Spring Web MVC从入门实例到实战教程

java 来源:互联网 作者:佚名 发布时间:2026-10-18 10:03:10 人浏览
摘要

1. Spring Web MVC核心概念 1.1 什么是Spring Web MVC Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中,其正式名称来源于源模块名称(spring-webmvc),通常简称为Spring MVC。

1. Spring Web MVC核心概念

1.1 什么是Spring Web MVC

Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中,其正式名称来源于源模块名称(spring-webmvc),通常简称为Spring MVC。

官方定义:Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning.

Servlet是Java Web开发的规范,定义了动态页面开发的技术标准,而Tomcat、Weblogic等Servlet容器则是该规范的具体实现,负责管理开发者编写的Servlet类。Spring MVC基于Servlet规范实现,为Web应用开发提供了完整的解决方案。

1.2 MVC设计模式深度解析

MVC是Model View Controller的缩写,是软件工程中的一种软件架构设计模式,将软件系统分为模型、视图和控制器三个基本部分,实现业务逻辑与界面展示的解耦。

1.2.1 MVC三大组件职责

  • Model(模型):应用程序的主体部分,负责处理数据逻辑和业务逻辑,包含数据的存储、处理和运算。
  • View(视图):专门用于与用户交互的界面,负责数据展示和接收用户操作,如HTML页面、移动端界面等。
  • Controller(控制器):作为视图与模型之间的桥梁,接收用户请求,选择对应的模型进行处理,并将处理结果通过视图返回给用户。

1.2.2 定义图与类比理解

MVC定义图

Spring MVC定义图

以饭店就餐场景为例,直观理解MVC组件的分工:

  • 服务员(View):接待顾客、记录点餐信息、上菜,负责与用户直接交互。
  • 前厅(Controller):接收服务员传递的订单,分配给对应的后厨处理,协调前后端流程。
  • 后厨(Model):根据订单需求制作菜品,处理核心业务逻辑。

1.3 Spring MVC与Spring Boot的关系

Spring Boot并非替代Spring MVC的框架,而是实现Spring MVC的一种便捷方式。两者的关系可通过下表清晰区分:

特性 Spring MVC Spring Boot
本质 Web框架,实现MVC模式 快速开发脚手架
核心作用 处理Web请求与响应 简化Spring应用配置与部署
依赖关系 可独立使用 可集成Spring MVC实现Web功能
发布时间 2004年 2014年

类比理解:Spring Boot如同一个功能完备的厨房,而Spring MVC则是厨房中实现烹饪功能的燃气灶和厨具。厨房(Spring Boot)可通过配置不同工具实现多种功能,而烹饪(Web开发)功能的核心实现依赖于燃气灶(Spring MVC)。

2. Spring MVC项目搭建与环境配置

2.1 项目创建步骤

Spring MVC项目通过Spring Boot方式创建,步骤如下:

  1. 新建Spring Boot项目,选择Spring Boot版本(推荐3.2.0及以上)。
  2. 在依赖选择界面勾选Spring Web模块(即Spring MVC核心依赖)。
  3. 配置项目基本信息(Group、Artifact、Package等),完成项目创建。

2.2 核心依赖说明

创建后的项目pom.xml文件中,Spring Web依赖自动引入,核心依赖代码如下:

1

2

3

4

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

</dependency>

该依赖包含Spring MVC核心组件、Servlet API、Tomcat嵌入式容器等关键资源,无需额外配置即可实现Web功能开发。

3. Spring MVC核心注解与应用

3.1 路由映射注解@RequestMapping

@RequestMapping是Spring MVC中最基础的路由映射注解,用于将URL请求与Java方法关联,支持修饰类和方法。

基础使用示例:

1

2

3

4

5

6

7

8

9

@RestController

@RequestMapping("/user") // 类级路由前缀

public class UserController {

    // 方法级路由,完整访问路径:/user/sayHi

    @RequestMapping("/sayHi")

    public String sayHi() {

        return "hello, Spring MVC";

    }

}

  • 类级注解:设置请求路径的初始前缀,所有方法路由需拼接该前缀。
  • 方法级注解:设置具体的请求路径,可支持多层路径(如/say/hi)。
  • 路径规则:URL路径最前是否加/不影响访问,Spring会自动补全(路径+请求方式是唯一的,可以相同的路径名字但是不同类型的请求)。

3.2 请求参数接收注解

3.2.1 @RequestParam参数重命名

用于解决前后端参数名称不一致问题,同时可设置参数是否必传:

1

2

3

4

5

@RequestMapping("/r6")

// 此处@RequestParam("sa")注解的作用是参数重命名,

public String r6(@RequestParam(value = "sa", required = false) String resouce){

    return "接收到 resouce = " + resouce;

}

  • value属性:指定前端传递的参数名称。
  • required属性:默认值为true,设置为false时参数非必传。

3.2.2 @PathVariable获取路径参数

用于从URL路径中直接提取参数,适用于RESTful风格接口:

1

2

3

4

@RequestMapping("/r11/{articleId}/{type}")

public String r11(@PathVariable("articleId") Integer id, @PathVariable String type){

    return "接收到的参数 articleId = " + id + ", type = " + type;

}

访问路径示例:http://127.0.0.1:8080/param/m8/5/zhangsan,其中5和zhangsan分别映射到id和userName参数。

3.3 响应处理注解

  • @ResponseBody:标识方法返回数据而非视图,可修饰类或方法。
  • @RestController:组合注解,等价于@Controller + @ResponseBody,类中所有方法默认返回数据。

两者区别示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 返回视图(需配合模板引擎)

@Controller

public class IndexController {

    @RequestMapping("/index")

    public String index() {

        return "/index.html";

    }

}

// 返回数据

@RestController

public class DataController {

    @RequestMapping("/data")

    public String getData() {

        return "这是返回的数据内容";

    }

}

4. 请求处理全场景实战

4.1 基础参数传递

4.1.1 单个参数接收

直接通过方法参数接收前端传递的参数,参数名称需与请求参数一致:

1

2

3

4

@RequestMapping("/r1")

public String r1(String name){

    return "接收到参数 name = " + name;

}

通过postman创建一个带有name参数请求访问示例:
http://127.0.0.1:8080/request/r1?name=zhangsan

4.1.2 多个参数接收

支持多个参数同时接收,参数顺序不影响绑定结果(请求的参数名称保持一致即可):

1

2

3

4

5

@RequestMapping("/r4")

    public String r4(String name, String password, Integer age){

        // 此处字符串拼接不考虑性能

        return "接收到参数 name = " + name + ", password = " + password + ", age = " + age;

    }

通过postman创建一个带有age,password,name参数请求访问示例:
http://127.0.0.1:8080/request/r4?age=20&name=zhangsan&password=123456

4.2 复杂参数处理

4.2.1 对象参数接收

当参数较多时,可封装为实体类接收,Spring会自动按属性名绑定:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

// 实体类

public class Person {

    private  String name;

    private String password;

    private int age;

    public String getName() {

        return name;

    }

    public String getPassword() {

        return password;

    }

    public int getAge() {

        return age;

    }

    public void setName(String name) {

        this.name = name;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    public void setAge(int age) {

        this.age = age;

    }

    @Override

    public String toString() {

        return "Person{" +

                "name='" + name + '\'' +

                ", password='" + password + '\'' +

                ", age=" + age +

                '}';

    }

}

// 接口方法

@RequestMapping("/r5")

public String r4(Person person){

    return "接收到参数 person = " + person;

}

创建post请求访问示例:http://127.0.0.1:8080/request/r5

4.2.2 参数重命名

通过@RequestParam()注解使得参数进行重命名与前端发的请求保持一致
且加了这个注解,此参数就为必传参数,如果不传则会报出400状态,除非将@RequestParam("sa")修改为@RequestParam(value = "sa", required = false)

1

2

3

4

5

@RequestMapping("/r6")

// 此处@RequestParam()注解的作用是参数重命名

public String r6(@RequestParam("sa") String resouce){

    return "接收到 resouce = " + resouce;

}

访问示例:http://127.0.0.1:8080/request/r6?sa=fyb_n_homepage

4.2.3 数组与集合参数

数组参数接收:

1

2

3

4

@RequestMapping("/r7")

public String r7(String[] names){

    return "接收到参数 names = " + Arrays.toString(names);

}

访问示例:
http://127.0.0.1:8080/request/r7?names=zhangsan&names=lisi&names=wangwu

也可以使用
http://127.0.0.1:8080/request/r7?names=zhangsan,lisi,wangwu

集合参数接收(需配合@RequestParam):

1

2

3

4

5

@RequestMapping("/r8")

// @RequestParam 在这里的作用是将请求中的参数绑定到方法的 List<String> names 参数上

public String r8(@RequestParam List<String> names){

    return "接收到的参数 names = " + names;

}

未使用@RequestPram绑定如图会报出500错误

绑定@RequestPram则正常状态

4.3 传递JSON数据

4.3.1 JSON 概念与优势

JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种轻量级的文本数据交互格式 ,基于 ECMAScript 规范的子集,采用独立于编程语言的语法存储和描述数据,核心作用是实现不同语言、不同系统间的数据传递与交换。
其核心优势如下:

  • 简单易用:语法贴近日常认知,仅需通过键值对、对象、数组三种结构即可描述数据,学习成本低,上手快; 跨平台兼容:支持 Java、Python、JavaScript、Go 等几乎所有主流编程语言,可在前后端、不同服务间无缝传输;
  • 轻量高效:相比 XML格式,JSON 数据无冗余标签,体积更小,传输时占用带宽少,能显著提升数据传输速度;
  • 结构灵活:支持对象嵌套数组、数组嵌套对象等复杂结构,可满足用户信息、订单详情等多维度数据描述需求;
  • 安全性高:本质是纯文本格式,不包含任何可执行代码,避免恶意脚本注入风险,常用于 Web 应用前后端交互、API 接口数据传输场景。

4.3.2 JSON 语法与核心结构

JSON 语法遵循严格规则,错误语法会导致解析失败,需重点关注以下要点:

1. 基础语法规则:

  • 数据以键值对(Key/Value)形式存储,Key 必须用双引号包裹(不可用单引号)
  • 不同数据之间用逗号分隔,末尾不可加多余逗号
  • 字符串类型值需用双引号包裹,数字、布尔值无需包裹
  • 注释:标准 JSON 不支持注释(部分解析工具如 JSON5
    支持,但不推荐跨系统使用)。

2. 两种核心结构:

  • 对象结构:用大括号{}包裹,存储无序键值对集合,适用于描述单个实体(如用户、商品),示例:

1

2

3

4

5

6

7

{

  "userId": 1001,

  "userName": "zhangsan",

  "age": 25,

  "isStudent": false,

  "hobbies": ["reading", "coding"]

}

数组结构:用中括号[]包裹,存储有序值列表,值类型可混合(如字符串、数字、对象),适用于描述多个同类实体(如用户列表、商品列表),示例:

1

2

3

4

5

6

[

  {"bookId": 1, "bookName": "Spring MVC实战"},

  {"bookId": 2, "bookName": "Java核心技术"},

  3.14,

  "JSON教程"

]

3. 合法 JSON 示例:
单个对象:{"name":"admin","age":18}
纯数组:["hello", 3.14, true]
对象数组:[{"name":"admin","age":18},{"name":"root","age":20}]

可通过在线 JSON 校验工具(如)验证语法正确性,避免因格式错误导致接口解析失败。

4.3.3 JSON 与 Java 对象互转(核心工具)

Spring MVC 框架默认集成jackson-databind工具包(Spring Web 依赖已包含),无需额外引入,可直接实现 JSON 字符串与 Java 对象的 “序列化”(对象转 JSON)和 “反序列化”(JSON 转对象)。

转换工具类实现
通过ObjectMapper类(jackson-databind 核心类)提供的方法完成转换,示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package cn.overthinker.springboot;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.junit.jupiter.api.Test;

public class JSONTests {

    private  static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {

        Person person = new Person();

        person.setName("zhangsan");

        person.setAge(18);

        person.setPassword("123456");

        // 对象转json字符串

        String s = objectMapper.writeValueAsString(person);

        System.out.println(s);

        //json字符串转对象

        String json = "{\"name\":\"zhangsan\",\"age\":18,\"password\":\"123456\"}";

        Person person1 = objectMapper.readValue(json, Person.class);

        System.out.println(person1);

    }

}

关键方法说明

  • writeValueAsString(Object obj):将 Java 对象转为 JSON 字符串,支持实体类、集合、Map等类型;
  • readValue(String jsonStr, Class valueType):将 JSON 字符串转为指定类型的Java 对象,需传入目标类的 Class对象;
  • 若转换集合(如List),需用TypeReference指定泛型类型,示例:

1

2

3

4

List<Person> personList = objectMapper.readValue(

    "[{\"id\":1,\"name\":\"zhangsan\"},{\"id\":2,\"name\":\"lisi\"}]",

    new TypeReference<List<Person>>() {}

);

4.3.4 Spring MVC 接收 JSON 请求

1. 前端请求方式(以 Postman 为例)

Postman 是后端开发常用的接口测试工具,传递 JSON 参数步骤如下:

  • 选择请求方式:推荐用 POST(GET 请求也支持,但JSON 数据需拼在 URL 中,不适用于复杂数据);
  • 设置请求URL:如http://127.0.0.1:8080/request/r9;
  • 配置请求头:在Headers标签中添加Content-Type:application/json(必须设置,告知后端请求数据格式为 JSON,否则解析失败);

2. 后端接口实现
后端需通过@RequestBody注解绑定请求正文,触发 Spring 的 JSON 解析逻辑,实现参数自动封装。

1

2

3

4

@RequestMapping("/r9")

public String r9(@RequestBody Person person){

    return "接收到的参数 person = " + person;

}

3. Fiddler抓包结果

4.4文件上传功能实现

使用@RequestPart注解实现文件上传功能:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

@RequestMapping("/r12")

    // 处理文件上传的请求方法,MultipartFile是Spring提供的文件上传封装类

    // throws IOException:声明可能抛出的IO异常(文件读写时可能发生)

    public String r12(MultipartFile file) throws IOException{

        // 1. 获取表单中文件参数的名称(即前端<input type="file" name="file">中的name值)

        // 注意:此名称是前端表单控件的name属性值,而非实际文件名

        System.out.println("表单文件参数名:" + file.getName());

        // 2. 获取上传文件的原始名称(包含文件名和扩展名,如"test.jpg")

        // 该名称来自客户端本地文件的名称,可能包含路径(不同浏览器处理不同,需注意)

        System.out.println("文件原始名称:" + file.getOriginalFilename());

        // 3. 获取文件的MIME类型(如图片为"image/jpeg",文本为"text/plain")

        // 用于判断文件类型,可用于限制上传文件格式(如只允许图片上传)

        System.out.println("文件MIME类型:" + file.getContentType());

        // 4. 定义文件保存路径和文件名

        // 这里将文件保存到本地"D:/temp/"目录,文件名使用原始文件名

        // 注意:需确保"D:/temp/"目录已存在,否则会抛出文件找不到异常

        File destFile = new File("D:/temp/" + file.getOriginalFilename());

        // 5. 将上传的文件内容转移到目标文件中

        // transferTo()是Spring提供的便捷方法,内部处理了文件流的读写和关闭

        // 替代了传统的InputStream/OutputStream手动读写逻辑,更安全高效

        file.transferTo(destFile);

        // 6. 返回上传成功的提示信息

        return "接受到文件,已保存至D:/temp目录";

    }

4.5 Cookie与Session会话管理

下述图中的"令牌"通常就存储在 Cookie 字段中,

4.5.1 Cookie操作

方式一:
通过HttpServletRequest 和HttpServletResponse 获取Cookie:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import jakarta.servlet.http.Cookie;

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

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

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

@RestController

@RequestMapping("/request2")

public class RequestController2 {

    /***

     * 读取cookie

     */

    @RequestMapping("/getCookie")

    public String getCookie(HttpServletRequest request, HttpServletResponse response) {

        Cookie[] cookies = request.getCookies();

        if(cookies != null){

            for(Cookie cookie : cookies){

                System.out.println(cookie.getName() + ":" + cookie.getValue());

            }

        }

        return "获取Cookie成功";

    }

}

方式二:
注解的方式

1

2

3

4

5

@RequestMapping("/getCookie2")

// 要求客户端必须返回含class名称的cookie

public String getCookie2(@CookieValue("class") String className) {

   return "获取Cookie成功 className:" + className;

}

演示步骤

  • 在idea启动服务器,打开浏览器新标签页,输入http://127.0.0.1:8080/request2/getCookie,显示获取Cookie成功

  • 按F12打开控制面板,选择Application,在左侧栏有个Cookies选项,点击找到http://127.0.0.1:8080,可以通过手动添加或者修改Cookie的值

  • 修改完后通过,进行页面刷新,回到idea观察日志,或者通过Fiddler抓包观察

4.5.2 Session操作

Session存储与读取:

方案一

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@RequestMapping("/setSession")

    public String setSession(HttpServletRequest request){

        HttpSession session = request.getSession();

        session.setAttribute("name", "zhangsan");

        session.setAttribute("age", 20);

        return "设置Session成功";

    }

    @RequestMapping("/getSession")

    public String getSession(HttpServletRequest request){

        HttpSession session = request.getSession();

        String name = (String) session.getAttribute("name");

        Integer age = (Integer) session.getAttribute("age");

        return "从session中获取数据, name:" + name + ", age:" + age;

    }

因为Session 是存储在服务器端的会话数据, 客户端(浏览器)无法直接访问服务器内存里的 Session 内容,只能通过后端接口 “间接读取”——getSession接口的作用就是把服务器内存里的 Session 数据返回给客户端,让前端能拿到这些信息(比如展示用户名称)。

在浏览器输入http://127.0.0.1:8080/request2/setSession刷新页面观察到session已经设置成功,同时打开f12,发现有一行数据就是sessionID

打开另一标签页输入http://127.0.0.1:8080/request2/getSession,可以观察到保存在session里面的信息

方案二:使用HttpSession

1

2

3

4

5

6

7

8

// 通过HttpSession直接获取session

@RequestMapping("/getSession")

public String getSession(HttpSession session){

    // 获取用户信息

    String name = (String) session.getAttribute("name");

    Integer age = (Integer) session.getAttribute("age");

    return "从session中获取数据, name:" + name + ", age:" + age;

}

方案三:通过@SessionAttribute注解

1

2

3

4

5

@RequestMapping("/getSession3")

public String getSession3(@SessionAttribute("name") String name){

    // 获取用户信息

    return "从session中获取数据, name:" + name;

}

提问与思考

当我们将name改为可自己输入的参数时,然后用设置不同的cookie的name参数值,那么它们如果交换sessionid,保存的信息也会交换吗?????

使用代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/***

     * 读取session

     * @param request

     * @return

     */

    @RequestMapping("/setSession")

    public String setSession(HttpServletRequest request, String name){

        HttpSession session = request.getSession();

        session.setAttribute("name", name);

        session.setAttribute("age", 20);

        return "设置Session成功";

    }

        // 通过HttpSession直接获取session

    @RequestMapping("/getSession2")

    public String getSession(HttpSession session){

        // 获取用户信息

        String name = (String) session.getAttribute("name");

        Integer age = (Integer) session.getAttribute("age");

        return "从session中获取数据, name:" + name + ", age:" + age;

    }

创建第一个Session(Chrome)
http://127.0.0.1:8080/request2/setSession?name=wangwu

得到的第一个SessionID为B76C84D38B4C522CAD16AE849F23414F

创建第二个Session(EDGE)

得到的第一个SessionID为FFC3B941551E94012D87BBBF3C95BC8A

将edge的sessionid替换为chrome的sessionid,观察现象

很明显的看到name值已经发生了改变,说明了Session 是基于服务器端的会话标识(SessionID)来区分用户的,不同客户端(浏览器)通过 SessionID 关联到对应的 Session 数据,同时服务器完全依赖 SessionID 来定位对应的 Session 数据

4.6获取Header

方案一

1

2

3

4

5

@RequestMapping("/getHeader")

public String getHeader(HttpServletRequest request){

    String userAgent = request.getHeader("User-Agent");

    return "从Header获取数据, userAgent" + userAgent;

}

方案二
使用@RequestHeader注解

1

2

3

4

5

//使用注解

  @RequestMapping("/getHeader2")

  public String getHeader(@RequestHeader("User-Agent") String userAgent){

      return "从Header获取数据, userAgent" + userAgent;

  }

运行结果(方案一)

5. 响应处理高级应用

5.1 静态页面返回

返回静态页面需使用@Controller注解(而非@RestController):

1

2

3

4

5

6

7

@Controller

public class IndexController {

    @RequestMapping("/index")

    public Object index() {

        return "/index.html";

    }

}

静态页面需放置在resources/static目录下,访问路径为:http://127.0.0.1:8080/index

5.2 JSON数据响应

Spring MVC可自动将对象转换为JSON格式响应:
示例一

1

2

3

4

5

6

7

8

9

@RequestMapping("/returnJson")

@ResponseBody

public HashMap<String, String> returnJson() {

    HashMap<String, String> map = new HashMap<>();

    map.put("Java", "Java Value");

    map.put("MySQL", "MySQL Value");

    map.put("Redis", "Redis Value");

    return map;

}

响应结果:

1

{"Java":"Java Value","MySQL":"MySQL Value","Redis":"Redis Value"}

示例二

1

2

3

4

5

6

7

8

9

10

11

12

@ResponseBody

@RequestMapping("/returnJSON")

public Person returnJSON(){

    // 实例化数据模型对象

    Person person = new Person();

    // 设置对象属性

    person.setName("zhangsan");

    person.setAge(18);

    person.setPassword("123456");

    // 返回对象,由 @ResponseBody 自动转换为 JSON

    return person;

}

响应结果:

1

{"name":"zhangsan","password":"123456","age":18}

5.3 响应状态码与Header设置

设置响应状态码:

1

2

3

4

5

6

@RequestMapping("/setStatus")

@ResponseBody

public String setStatus(HttpServletResponse response) {

    response.setStatus(401); // 未授权状态码

    return "设置状态码成功";

}

设置自定义Header:

1

2

3

4

5

6

@RequestMapping("/setHeader")

@ResponseBody

public String setHeader(HttpServletResponse response) {

    response.setHeader("MyHeader", "MyHeaderValue");

    return "设置Header成功";

}

6. 综合项目实战

6.1 加法计算器

6.1.1 接口设计

  • 请求路径:/calc/sum
  • 请求方式:GET/POST
  • 参数:num1(Integer,必填)、num2(Integer,必填)
  • 响应:计算结果HTML页面

6.1.2 后端代码

1

2

3

4

5

6

7

8

9

@RestController

@RequestMapping("/calc")

public class CalcController {

    @RequestMapping("/sum")

    public String sum(Integer num1, Integer num2) {

        Integer sum = num1 + num2;

        return "<h1>计算机计算结果: " + sum + "</h1>";

    }

}

6.1.3 前端页面

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>加法计算器</title>

</head>

<body>

    <form action="calc/sum" method="post">

        <h1>计算器</h1>

        数字1:<input name="num1" type="text">

        数字2:<input name="num2" type="text">

        <input type="submit" value="点击相加">

    </form>

</body>

</html>

效果演示

6.2 用户登录系统

6.2.1 核心功能

  1. 账号密码校验
  2. 登录状态保持(Session)
  3. 首页显示当前登录用户

6.2.2 后端代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

@RestController

@RequestMapping("/user")

public class LoginController {

    // 登录校验

    @RequestMapping("/login")

    public boolean login(String userName, String password, HttpSession session) {

        if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {

            return false;

        }

        // 模拟数据库校验

        if ("zhangsan".equals(userName) && "123456".equals(password)) {

            session.setAttribute("userName", userName);

            return true;

        }

        return false;

    }

    // 获取当前登录用户

    @RequestMapping("/getLoginUser")

    public String getLoginUser(HttpSession session) {

        String userName = (String) session.getAttribute("userName");

        if (StringUtils.hasLength(userName)) {

            return userName;

        }

        return "";

    }

}

6.3 图书管理系统

6.3.1 系统功能

  1. 用户登录验证
  2. 图书列表展示
  3. 图书状态处理

6.3.2 核心代码

图书列表接口:

1

2

3

4

5

6

7

8

9

@RestController

@RequestMapping("/book")

public class BookController {

    @RequestMapping("/getList")

    public List<BookInfo> getList() {

        BookService bookService = new BookService();

        return bookService.getBookList();

    }

}

前端页面渲染:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

function getBookList() {

    $.ajax({

        type: "get",

        url: "/book/getList",

        success: function (result) {

            if (result != null) {

                var finalHtml = "";

                for (var book of result) {

                    finalHtml += '<tr>';

                    finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '"></td>';

                    finalHtml += '<td>' + book.id + '</td>';

                    finalHtml += '<td>' + book.bookName + '</td>';

                    finalHtml += '<td>' + book.author + '</td>';

                    finalHtml += '<td>' + book.count + '</td>';

                    finalHtml += '<td>' + book.price + '</td>';

                    finalHtml += '<td>' + book.publish + '</td>';

                    finalHtml += '<td>' + book.statusCN + '</td>';

                    finalHtml += '<td><a href="book_update.html?bookId=' + book.id + '" rel="external nofollow" >修改</a> | <a href="javascript:deleteBook(' + book.id + ')" rel="external nofollow" >删除</a></td>';

                    finalHtml += "</tr>";

                }

                $("tbody").html(finalHtml);

            }

        }

    });

}

7. 开发工具与效率提升

7.1 Postman接口测试

Postman是后端开发常用的接口测试工具,支持多种请求方式、参数类型,无需编写前端代码即可完成接口测试。

核心使用步骤:

  1. 下载安装:
  2. 创建请求:选择请求方式(GET/POST)、输入URL
  3. 配置参数:根据接口类型选择参数格式(Query Params、form-data、JSON等)
  4. 发送请求:点击Send按钮,查看响应结果

工作界面展示

7.2 Lombok简化开发

Lombok是Java开发工具库,通过注解自动生成getter/setter、toString等冗余代码,简化开发流程。

7.2.1 依赖引入

1

2

3

4

5

<dependency>

    <groupId>org.projectlombok</groupId>

    <artifactId>lombok</artifactId>

    <optional>true</optional>

</dependency>

7.2.2 常用注解

注解 作用
@Data 生成getter/setter、toString、equals等方法
@Getter 仅生成getter方法
@Setter 仅生成setter方法
@NoArgsConstructor 生成无参构造方法
@AllArgsConstructor 生成全参构造方法

使用示例:

1

2

3

4

5

6

7

8

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Person {

    private int id;

    private String name;

    private String password;

}

8. 企业开发规范

遵循以下开发规范可提升代码可读性和维护性,符合企业级开发标准:

  1. 命名规范:
    • 类名:大驼峰风格(如UserController)
    • 方法名、参数名、变量名:小驼峰风格(如getUserName)
    • 包名:全小写,多单词用点分隔(如com.example.demo.controller)
  2. 代码格式:
    • 缩进:4个空格缩进,避免使用Tab
    • 注释:关键业务逻辑添加单行注释,类和方法添加文档注释
    • 空行:不同逻辑块之间添加空行,增强可读性
  3. 注解使用:
    • 注解属性较多时,每个属性单独一行
    • 优先使用组合注解(如@RestController替代@Controller+@ResponseBody)

版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计