初识Spring(1)——mvc概念,部分常用注解

1、什么是Spring Web MVC?

Spring MVC 是一种基于 Java 的实现了 MVC(Model-View-Controller,模型 - 视图 - 控制器)设计模式的 Web 应用框架,它是 Spring 框架的一个重要组成部分,用于构建 Web 应用程序。

1.1 MVC定义

MVC是Model,View,Controller的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分。

**View(视图):**指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.

**Model(模型):**是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.

**Controller(控制器):**可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型 。

1.2 什么是Spring MVC?

Sping MVC是对MVC架构的实现,是一个Web框架,不过Sping MVC中MVC的架构稍有改变

浏览器发来的请求将直接通过控制器简单处理后,传给对应的模型而不经过视图。

对于Spring MVC,当用户在浏览器中输入了URL之后是如何感知到用户的请求并给予相应的?

主要分以下三个方面:

  1. 建⽴连接:将用户(浏览器)和Java程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring程序。

  2. 请求:⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数

    的功能。

  3. 响应:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾,也就是响应. 。

1.2.1 传递参数

下面四种分别体现了get和post的两种实现方式

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping(value = "/v1",method = RequestMethod.GET)
    public String v1() {
        return "Hello method = RequestMethod.GET";
    }
    @GetMapping("/v2")
    public String v2() {
        return "Hello GetMapping";
    }

    @RequestMapping(value = "/v3", method = RequestMethod.POST)
    public String v3() {
        return "Hello method = RequestMethod.POST";
    }
    @PostMapping("/v4")
    public String v4() {
        return "Hello PostMapping";
    }
}

1.2.2 传递对象

  • 如果参数⽐较多时,⽅法声明就需要有很多形参.并且后续每次新增⼀个参数,也需要修改⽅法声明.
  • 我们不妨把这些参数封装为⼀个对象.
  • SpringMVC也可以⾃动实现对象参数的赋值,⽐如Person对象:
  • 需要注意的是对象类必须完成get和set方法Spring才能赋值和取值
java 复制代码
public class Person {
private int id;
private String name;
private String password;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}

传递对象代码实现:

java 复制代码
@RequestMapping("/m3")
public Object method3(Person p){
return p.toString();
}  

1.2.3 给参数重命名

前后端对同一个参数名称命名习惯可能不同,比如对于用户名,前端有可能是userName,后端是name。这种情况就需要给参数重命名。

创建前端请求:

后端使用**@RequestParam**注解:

前端得到的相应:

如果此时前端名称改为name,即和后端参数列表中同一参数名一样是不能传递成功的:

就是说后端只认重命名注解中的名字。

还有一点需要注意的是,当对一个参数使用了**@RequestParam**注解时,这个参数就默认成为了必传参数,即前端如果没有传递该参数,会产生请求错误:


可以得出结论:

  1. 使⽤**@RequestParam** 进⾏参数重命名时,请求参数只能和**@RequestParam** 声明的名称⼀

    致,才能进⾏参数绑定和赋值.

  2. 使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数.

如果我们的实际业务前端的参数是⼀个⾮必传的参数,针对上述问题,如何解决呢?

先来了解下参数必传的原因,我们查看 @RequestParam 注解的实现细节就可以发现端倪,注解实现如下:

java 复制代码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

可以看到 required 的默认值为true,表⽰含义就是:该注解修饰的参数默认为必传。既然如此,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,

具体实现如下 :

java 复制代码
 @RequestMapping("/v3")
    public String v3(@RequestParam(value = "userName",required = false) String name, Integer age){
            return name + " " + age;
    }

此时被**@RequestParam**注解的参数就不是必传参数了

1.2.4 传递数组

代码如下:

java 复制代码
 @RequestMapping("/v4")
    public String v4(String[] array){
        System.out.println(array.length);
        return Arrays.toString(array);
    }

前端可以这样传

  1. 后端也可以看到数组长度为4

同一个参数传多次,也会被认为同一个数组,后端也可以看到数组长度为3

1.2.5 传递List

java 复制代码
 @RequestMapping("/v5")
    public String v5(@RequestParam List<String> list){
        System.out.println(list.size());
        return Arrays.toString(list.toArray());
    }

需要用**@RequestParam**对参数进行标记

1.3 传递JSON数据

1.3.1 JSON的语法:

  1. 数据在键值对(Key/Value) 中
  2. 数据由逗号**,**分隔
  3. 对象⽤ {} 表示
  4. 数组⽤** \[\]** 表示
  5. 值可以为对象,也可以为数组,数组中可以包含多个对象

1.3.2 JSON的两种结构

  1. 对象:⼤括号 {} 保存的对象是⼀个⽆序的键值对集合。⼀个对象以左括号 { 开始,右括号 }
    结束。每个"键"后跟⼀个冒号 : ,键值对使⽤逗号 , 分隔
  2. 数组:中括号 \[\] 保存的数组是值(value)的有序集合.⼀个数组以左中括号 开始,右中括 号 结束,值之间使⽤逗号 , 分隔。

如下:

1.3.3 Json字符串和Java对象的转换

JSON本质上是⼀个字符串,通过⽂本来存储和描述数据。

SpringMVC框架也集成了JSON的转换⼯具,我们可以直接使⽤,来完成JSON字符串和Java对象的互转。

java 复制代码
//对象
public class User {
    String name;
    int age;
    String gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

使⽤ObjectMapper对象提供的两个⽅法,可以完成对象和JSON字符串的互转

writeValueAsString:把对象转为JSON字符串

readValue:把字符串转为对象

java 复制代码
public class JsonTest {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();

        User user = new User();
        user.age = 17;
        user.name = "火车";

        //对象转json
        String s = objectMapper.writeValueAsString(user);
        System.out.println("json字符串:" + s);

        //json转对象
        User user1 = objectMapper.readValue(s, user.getClass());
        System.out.println(user1);
    }
}

运行结果:

Json字符串和Java对象的转换本质上是jackson-databind提供的功能,SpringMVC框架中已经把该⼯具包引⼊了进来,咱们直接使⽤即可,如果脱离SpringMVC使⽤,需要引⼊相关依赖

xml 复制代码
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.5</version>
</dependency>

1.3.4 传递Json对象

接受JSON对象,需要使用**@RequsetBody**注解。

java 复制代码
@RequestMapping("/v6")
public String v6(@RequestBody User user){
    return user.toString();
}

1.4 获取URL中的参数

使用**@PathVariable**注解

java 复制代码
@RequestMapping("/user/{id}/{name}")
    public String getArticle(@PathVariable("id") String id,@PathVariable("name") String name){
        return "id:" + id + "\n" + "name:" +name;
    }

1.5上传文件

java 复制代码
@RequestMapping("/v7")
    public String getFile(@RequestPart("file")MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        file.transferTo(new File("f:\\重头来过\\" + file.getOriginalFilename()));
        return "接收到文件名称为: " + originalFilename;
    }

可以看到上传成功

二、总结

  1. @RequestMapping:路由映射
  2. @RequestParam:后端参数重命名
  3. @RequestBody:接收JSON类型的参数
  4. @PathVariable:接收路径参数
  5. @RequestPart:上传⽂件
相关推荐
xcl09254 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐5 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长6 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn6 小时前
Spring 注解使用详解
java·spring
一条小小yu6 小时前
Spring IoC的理解
java·后端·spring
落魄实习生6 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈6 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白8 小时前
核心功能(Service接口)
java·mybatis
乌暮9 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习