Spring MVC上篇

 ~

目录

1.什么是Spring MVC

2.为什么要学Spring MVC

3.Spring MVC的三大核心

3.1Spring MVC的创建与连接

3.1.1创建一个Spring MVC项目

3.1.2@RequestMapping注解

3.1.3@GetMapping注解

3.1.4@PostMapping注解

4.获取参数

4.1传递单个参数

4.2传递多个参数

4.3传递对象

4.4后端参数重命名

4.5获取Json对象

4.6获取URL中的参数

4.7上传文件 


1.什么是Spring MVC

①官网定义译为中文:

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来自其源模块的名称(Spring-webmvc),但它通常被称为“Spring MVC” 。
我们可以由上述定义,得到两个点:
a.Spring MVC是一个web框架
b.Spring MVC是基于Servlet API来进行构建的
②什么是MVC?
MVC:Model View Controller翻译中文就是“模型,视图,控制器”,它是一种设计模式,这种设计模式将软件(项目)分为三部分:模型,视图和控制器。
(需要注意的是视图一般分为服务器视图和客户端视图,而在这里我们所说的视图指的是服务器视图)

③MVC和Spring MVC的关系:

MVC是一种设计思想,而Spring MVC更可以说是它的一种实现(一种具体的实现框架)

④用自己的理解来谈谈Spring MVC:

Spring MVC是一个基于MVC设计模式和Servlet API实现的Web项目,同时Spring MVC又是Spring框架中的一个Web模块,它是随着Spring诞生而存在的一个框架 

2.为什么要学Spring MVC

之所以要学习 Spring MVC 是因为它是⼀切项目的基础,我们以后创建的所有 Spring、
Spring Boot 项目基本都是基于 Spring MVC 的。

3.Spring MVC的三大核心

换句话说可以说是我们需要掌握的方法:

①实现用户和程序的映射(用户在URL输入地址之后,能够在程序里找到相应的方法)

②服务器端要得到用户的请求参数

③服务器端要将结果返回给用户(前端)

下面将依次对这几个板块进行介绍

3.1Spring MVC的创建与连接

3.1.1创建一个Spring MVC项目

创建一个Spring MVC项目实质上就是创建一个Spring Boot项目,在配置中选取引入MVC即可。图解步骤如下:(前面Spring Boot创建之前有写过,这里就不作重复了)

实现用户和程序的映射主要有以下三种方法

3.1.2@RequestMapping注解

①用法:

@RequestMapping(“/xxx”)

既可以用于类上,也可以放于方法上,访问地址就是类地址+方法地址

②示例:

a.我们随意创建一个页面来访问:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController1 {
    @ResponseBody//返回一个非静态页面
    @RequestMapping("/hello")
    public String  sayhi(){
        System.out.println("hello spring mvc");
        return "hello spring mvc";
    }
}

结果如下:

 b.我们能够知道直接通过url访问的,那么必然是get请求,我们来抓一下包,看看自己的判断是否是正确的:

我们可以发现确实是get请求,那么要是我们用post请求来完成是否可以呢? 

我们用postman来进行测试一下:

我们就发现默认情况下,@RequestMapping既可以支持get请求,又可以支持post请求 。但是,我们仍然可以对参数进行拓展

c.@RequestMapping参数拓展:(让其只支持一种访问方式,我们这里以post为例)

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController1 {
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST,value = "/hello")
    public String  sayhi(){
        System.out.println("hello spring mvc");
        return "hello spring mvc";
    }
}

我们现在可以看到参数里已经指定了method为post,这个时候我们显然是不能够通过URL来访问的,因此,我们用postman来测试现在它支持的形式:

(1)当为post的时候,如预期,没有问题

这个时候我们抓包fiddler也是得到同样的情况:

 (2)当为GET的情况:

我们会发现这样就出现了问题。那么也就是这种指定方式是只能支持指定的一种 。

当然,指定为某种,我们也可以采用更简单的如下方式

3.1.3@GetMapping注解

①用法:

@GetMapping(“/xxx”)

②示例:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController1 {
    @ResponseBody
    @GetMapping("/hello")
    public String  sayhi(){
        System.out.println("hello spring mvc");
        return "hello spring mvc";
    }
}

结果如下:

3.1.4@PostMapping注解

①用法:

@PostMapping(/xxx”)

②示例:(POST是无法直接通过URL访问到的,我们需要通过postman来进行测试)

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class UserController1 {
    @ResponseBody
    @PostMapping("/hello")
    public String  sayhi(){
        System.out.println("hello spring mvc");
        return "hello spring mvc";
    }
}

结果如下:

4.获取参数

4.1传递单个参数

①解释:

直接在方法中传入一个参数

②示例:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController2 {
    @ResponseBody
    @RequestMapping("/getuserid")
    public Student student(Integer id){//这里必须使用包装类,否则会报错
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        student.setAge(18);
        student.setPassword("123456");
        return student;
    }
}

结果如下:

③注意!!

 此传递名称需要与前端传递的产生名保持一致,否则就获取不到参数的值。如下:

4.2传递多个参数

①说明:

顾名思义就是传递多个参数

②示例:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController2 {
    @ResponseBody
    @RequestMapping("/getuserid")
    public String student(Integer id,String name){//这里必须使用包装类,否则会报错
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        student.setAge(18);
        student.setPassword("123456");
        return "id: " + id+ " | name: " + name;
    }
}

结果如下:

4.3传递对象

当参数非常多的时候,显然这个时候代码的可读性就大大降低了,所以我们为了增强代码的可读性,我们决定使用传递对象。

①说明:

传递对象顾名思义是对整个对象来进行封装传递

②示例:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController3 {
    @ResponseBody//返回一个非静态页面
    @RequestMapping("/object")
    public String reg(Student student){
        return "学生的基本信息"+student;
    }
}

输出结果:

注意:

虽然我们在代码中传递的是对象,但是不要忘记,在url中我们还是应该输入需要参数的值,否则就会出现为null的如下情况

4.4后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可能不一致,比如前端传递了一个username给后端,而后端又是name字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使用@RequestParam来重命名前后端的参数值。

①示例前后端不一致时会出现的错误:

而有时候面临这个情况,前后端都不愿意选择让步,所以我们引入@RequestParam来进行处理

②引入后处理:

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController2 {
    @ResponseBody
    @RequestMapping("/getuserid")
    public String student(@RequestParam("username") String name){//这里必须使用包装类,否则会报错
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        student.setAge(18);
        student.setPassword("123456");
        return "name: " + name;
    }
}

输出结果:(如果有多个参数需要改名,就用多个@RequestParam即可)

 ③注意:当采用了@RequestParam后,要是不传参数就会报错如下:

而当没有这个注解的时候,没传参数就会默认为null如下:

 ④解决③中当有@RequestParam注解不传参时报错的情况:

(我们会发现在默认情况下,一定要传参数,否则就会报错)

如果想要解决此问题,可以给@RequestParam里面添加required=false,这样不传参数就也不会报错

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController2 {
    @ResponseBody
    @RequestMapping("/getuserid")
    public String student(@RequestParam(name="username",required = false) String name){//这里必须使用包装类,否则会报错
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        student.setAge(18);
        student.setPassword("123456");
        return "name: " + name;
    }
}

结果如下: 

4.5获取Json对象

如果需要接收json格式的对象,那么我们就必须添加@RequestBody这个注解

①未添加@RequestBody注解的情况:

我们用fiddler来进行抓包,来看这个是什么形式:

 可以看出此时并不是json格式的,这个的输出结果是这样:

②当我们加了@RequestBody后的情况:

 这个时候我们访问fiddler,也可以看到现在的类型究竟是什么:

4.6获取URL中的参数

①此处URL中的参数的含义:

直接拿URL地址中的参数,简单来说,就是从URL中?前面的字段中获取参数。

举个例子:

②为什么要获取URL中的参数?

因为某些软件或者游戏为了增加曝光度的话,当我们搜索其角色或者是内容名字,要是它加在?后的话,曝光率相比于加在?前会大大降低,所以更多的商家,就将其参数放于?前的URL中。

③格式:

a.在@RequestMapping(“/xxx/{参数1}{参数2}”) 

b.在方法中加上@PathVariable注解

④示例如下:

package com.example.demo;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController4 {
    @ResponseBody
    @RequestMapping("/getThing/{id}/{name}")
    public String getThing(@PathVariable Integer id,@PathVariable String name){
        return "id:"+id+"name:"+name;
    }
}

这样当我们在URL里输入id为1,name为小乔时,就会出现如下结果:

4.7上传文件

①格式:

用@RequestPart注解

②示例:保存路径写死的情况

package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Slf4j
@Controller
@ResponseBody //返回一个非静态页面
public class UserController5 {
    //上传文件
    @RequestMapping("/upimg")
    public boolean upImg(Integer id, @RequestPart("img") MultipartFile file) {
        boolean result = false;
        //保存文件到本地目录
        try {
            file.transferTo(new File("C:\\zhuomian\\222.png"));
            result = true;
        } catch (IOException e) {
            log.error("上传图片失败" + e.getMessage());
        }
        return result;
    }
}

我们用postman来看示例是否成功:

然后我们会发现在桌面上多了一个222.png

 而在实际开发中,我们的保存路径却并没有写死,所以我们要用更符合实际开发的来写:

②保存路径不写死的情况:

a.因为在公司中会涉及不同的测试,开发环境,运行环境等等,然而当环境改变的时候,为了使我们更加方便,所以我们引入相应的配置,最终的时候,只需要修改一行配置,就可以完成切换。如下,我们设置三个yml配置文件。

我们这里就用yml文件来进行演示,需要注意的是,前面的application是固定的,我们只需要更改后面的名称即可。

(1)主配置文件application.yml中来配置配置文件的运行平台

# 设置配置文件的运行平台
spring:
  profiles:
    active: xxx
    # 如运行application-dev配置文件 即active: dev

(2)在不同的环境下配置不同的参数,如在开发配置文件中配置图片保存路径:

# 文件保存路径
img:
  path: C:\\zhuomian\\

b.而在这种情况下,我们要保存图片到任意路径的话,需要操作以下几步:

(1)配置并获取保存的路径

(2)利用(UUID)来保持图片名称的唯一性

(在此步要获取到名片的格式,并且将UUID与图片的格式拼接在一起)

(3)储存图片

代码如下:

package com.example.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@Controller
@ResponseBody //返回一个非静态页面

public class UserController5 {
    //获取配置文件的保存路径
    @Value("${img.path}")
    private String imgpath;
    //上传文件
    @RequestMapping("/upimg")
    public boolean updateImg(Integer id, @RequestPart("img") MultipartFile file) {
        boolean result = false;
        //得到原图片的名称
        String filename = file.getOriginalFilename();
        //得到图片后缀(png)
        String fixType = filename.substring(filename.lastIndexOf("."));
        //生成不重名的文件名
        filename = UUID.randomUUID().toString() + filename;
        try {
            //将图片保存
            file.transferTo(new File(imgpath + filename));
            result = true;
        } catch (IOException e) {
            log.error("图片上传失败!" + e.getMessage());
        }
        return result;
    }

}

postman来测试:

 测试结果如下:

测试成功 

目录少写了cookie,header,session的获取,下期我们再补上哦,顺便把MVC内容讲完

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张洋洋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值