Spring MVC程序开发

目录

1.什么是Spring MVC?

1.1MVC定义

1.2MVC和Spring MVC的关系

2.为什么要学习Spring MVC?

3.怎么学Spring MVC?

3.1Spring MVC的创建和连接

3.1.1创建Spring MVC项目

3.1.2@RequestMapping 注解介绍

3.1.3 @RequestMapping 是 post 还是 get 请求?

​编辑 3.1.4 @GetMapping 和 PostMapping

3.2 获取参数

3.2.1 传递单个参数

3.2.2 传递对象

3.2.3 表单参数传递/传递多个参数(⾮对象)

 

3.2.4 后端参数重命名(后端参数映射)

3.2.5 设置参数必传@RequestParam

3.2.6 @RequestBody 接收JSON对象

3.2.7 获取URL中参数@PathVariable

3.2.8 上传⽂件@RequestPart

3.2.9 获取Cookie/Session/header

​编辑 3.2.10返回Jason对象

4.请求转发和请求重定向


1.什么是Spring MVC?

官⽅对于 Spring MVC 的描述是这样的:
Spring Web MVC is the original web framework built on the Servlet API and has been included
comes from the name of its source module (
in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,”
Spring Web MVC is the original web framework built on the Servlet API and has been included
spring-webmvc as “Spring MVC”. ), but it is more commonly known as “Spring MVC”.
翻译成中文:
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为“Spring MVC”。
上述定义中我们可以得出两个关键信息:
1.Spring MVC是一个Web框架。
2.SPring MVC是基于servlet API构建的。
然⽽要真正的理解什么是 Spring MVC?我们⾸先要搞清楚什么是 MVC?

1.1MVC定义

MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。
Model(模型)是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
View(视图)是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。
Controller(控制器)是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据,
控制⽤户输⼊,并向模型发送数据。

1.2MVC和Spring MVC的关系

MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。
总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web 框架,那么当⽤户在浏览器中输⼊了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求。

2.为什么要学习Spring MVC?

现在绝⼤部分的 Java 项⽬都是基于 Spring(或 Spring Boot)的,⽽ Spring 的核⼼就是 Spring
MVC。也就是说 Spring MVC 是 Spring 框架的核⼼模块,⽽ Spring Boot 是 Spring 的脚⼿架,因此我们可以推断出,现在市⾯上绝⼤部分的 Java 项⽬约等于 Spring MVC 项⽬,这是我们要学 Spring MVC 的原因。
在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架,如下图所
示:
简单来说,咱们之所以要学习 Spring MVC 是因为它是⼀切项⽬的基础,我们以后创建的所有
Spring、Spring Boot 项⽬基本都是基于 Spring MVC 的。

3.怎么学Spring MVC?

学习 Spring MVC 我们只需要掌握以下 3 个功能:
1. 连接的功能:将⽤户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的
Spring 程序。
2. 获取参数的功能:⽤户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
3. 输出数据的功能:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤户。
对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC。

3.1Spring MVC的创建和连接

Spring MVC 项⽬创建和 Spring Boot 创建项⽬相同(Spring MVC 使⽤ Spring Boot 的⽅式创建),在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项⽬。
在 Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作⽤。

3.1.1创建Spring MVC项目

Spring MVC 可以基于 Spring Boot 创建,也就是创建⼀个 Spring Boot 项⽬,勾选上 Spring Web
模块即可,如下图所示:

接下来,创建⼀个类,实现⽤户到 Spring 程序的互联互通,具体实现代码如下:

@Controller//让Spring框架启动时加载
@ResponseBody//返回非页面数据
@RequestMapping("/user")//路由器规则注册
public class UserController {
    @RequestMapping("/hi")
    public String sayHi(){
        return "hi,Spring MVC";

    }
}

访问地址127.0.0.1:8081/user/hi就可以打印出想要的文字:

3.1.2@RequestMapping 注解介绍

@RequestMapping 是 Spring Web 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的路
由映射的。
路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类
的某个⽅法的过程就叫路由映射。

@RequestMapping的基础使用:

@Controller
@RequestMapping("/web")
public class WebController {
    @RequestMapping("/index")
    public String index(){
//        return "hello,springmvc";
        return "/index.html";
    }
    @ResponseBody
//    @RequestMapping(value = "/indexData",method = RequestMethod.POST)
//    @PostMapping("/indexData")
    @GetMapping("/indexData")
    public String indexData(){
        return "hello,springmvc";
//        return "/index.html";
    }
}
@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + 方法。
@RequestMapping 也可以直接修饰⽅法,代码实现如下:
@Controller
@ResponseBody
public class UserController1 {
    @RequestMapping("/hi")
    public String sayHi(){
        return "hi,Spring";
    }
}

3.1.3 @RequestMapping 是 post 还是 get 请求?

使⽤ PostMan 测试⼀下,默认情况下使⽤注解 @RequestMapping 是否可以接收 GET 或 POST 请求?

根据postman可以发现,@RequestMapping既有post请求,也有get请求。那如果只想要post或者get请求呢?

指定 GET/POST ⽅法类型:

我们可以显示的指定 @RequestMapping 来接收 GET的情况,如下所示:
public class UserController1 {
    @RequestMapping(value = "/hi2",method = RequestMethod.GET)
    public String sayHi2(){
        return "hi,Spring";
    }
}

 3.1.4 @GetMapping 和 PostMapping

get 请求的 3 种写法:
//写法1
@RequestMapping("/hi2")
//写法2
@RequestMapping(value = "/hi2",method = RequestMethod.GET)
//写法3
@GetMapping("hi2")

post请求的2种写法:

//写法1
@RequestMapping(value = "hi2",method = RequestMethod.POST)
//写法2
@PostMapping("hi2")

3.2 获取参数

3.2.1 传递单个参数

在 Spring MVC 中可以直接⽤⽅法中的参数来实现传参,⽐如以下代码:

    @RequestMapping("/get2")
    public String get2(String name){
        return "name:"+name;
    }

 在 postman 中访问⽅法:

3.2.2 传递对象

并且 Spring MVC 可以⾃动实现参数对象的赋值,⽐如Student对象:

@Data
public class Student {
    private Integer id;
    private  String name;
    private Integer age;
    private String nickname;
}

 传递对象代码实现:

    @RequestMapping("/get6")
    public String get6(Student student){
        return student.toString();
    }
前端访问:

最终执行结果:

3.2.3 表单参数传递/传递多个参数(⾮对象)

    @RequestMapping("/get3")
    public String get3(String name,Integer age){
        return "name:"+name+","+"age:"+age;
    }

重要说明:当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果。

3.2.4 后端参数重命名(后端参数映射)

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个time 给后端,⽽后端⼜是有 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值。
具体示例如下,后端实现代码:
    @RequestMapping("/m4")
    public Object method4(@RequestParam("time") String createtime){
        System.out.println("时间:" + createtime);
        return "/index.html";
    }

3.2.5 设置参数必传@RequestParam

上⾯的列⼦,如果我们是前端传递⼀个⾮ time 的参数,就会出现程序报错的情况,如下图所示:

这是因为后端已经声明了前端必须传递⼀个 time 的参数,但是前端没有给后端传递,我们查看
@RequestParam 注解的实现细节就可以发现端倪,注解实现如下:

⾮必传参数设置

如果我们的实际业务前端的参数是⼀个⾮必传的参数,我们可以通过设置 @RequestParam 中的
required=false 来避免不传递时报错,具体实现如下:
    @RequestMapping("/m4")
    public Object method4(@RequestParam(value = "time",required = false) String createtime) 
    {
        System.out.println("时间:" + createtime);
        return "/index.html";
    }

3.2.6 @RequestBody 接收JSON对象

后端接收代码:

    @RequestMapping("/get8")
    public String get8(@RequestBody Student student){
        log.info(student.toString());
        return student.toString();
    }

3.2.7 获取URL中参数@PathVariable

后端实现代码:

    //取url地址
    @RequestMapping("/get9/{shopid}/{dealid}")
    public String get9(@PathVariable Integer shopid,@PathVariable("dealid") Integer dealId) 
    {
        return "shopid:"+shopid+",dealId:"+dealId;
    }

字段需要保持一致,如果不一致,需要在@PathVariable设置参数的名称 

3.2.8 上传⽂件@RequestPart

后端代码实现:

    @RequestMapping("/get10")
    public String get10(@RequestPart("file") MultipartFile file) throws IOException {
        log.info(file.getOriginalFilename());
        file.transferTo(new File("D:/temp/"+file.getOriginalFilename()));
        return "success";
    }

3.2.9 获取Cookie/Session/header

后端代码实现:

使用@CookieValue注解来实现

    @RequestMapping("/get11")
    public String grt11(@CookieValue(name = "bite1",required = false) String bite){
        return "bite:"+bite;
    }

如果cookie中不存在这个key,就会报错

我们手动设置cookie,页面就会访问成功,所以cookie是可以造假的。

获取session:

后端代码实现:

    @RequestMapping("/get12")
    public String grt12(@SessionAttribute(required = false) String username){
        return "username:"+username;
    }

直接执行是获取不到session的,我们需要在后端中设置session 

设置session:

后端代码实现:
 

    @RequestMapping("/set1")
    public String set1(HttpSession session){
        session.setAttribute("username","bite");
        return "success";
    }

先执行这个方法,就会在前端获取到session:

 session在存储时就是以键值对的方式存储的

获取header:

后端代码实现:

    @RequestMapping("/get13")
    public String get13(@RequestHeader("User-Agent") String userAgent){
        return "userAgent:"+userAgent;
    }

 3.2.10返回Jason对象

    @RequestMapping("/get14")
    public Map<String,String> get14(){
        Map<String,String>map=new HashMap<>();
        map.put("k1","v1");
        map.put("k2","v2");
        map.put("k3","v3");
        map.put("k4","v4");
        map.put("k5","v5");
        return map;
    }

 

使用filder抓包:

4.请求转发和请求重定向

return 不但可以返回⼀个视图,还可以实现跳转,跳转的⽅式有两种:
forward 是请求转发;
redirect:请求重定向。
请求转发和重定向的使⽤对⽐:
@Controller
@RequestMapping("/index")
public class IndexController {
    /**
     * 请求转发
     * @return
     */
    @RequestMapping("/forward")
    public String forward(){
        return "forward:/index.html";
    }
    @RequestMapping("/redirect")
    public String redirect(){
        return "redirect:/index.html";
    }
}
举例说明 forward 和 redirect
forward(请求转发)和 redirect(请求重定向)的区别,举例来说,例如,你告诉你妈妈,你想吃辣条,如果你妈妈,说好,我帮你去买,这就是 forward 请求转发;如果你妈妈让你⾃⼰去买,那么就是请求 redirect 重定向。
“转发”和“重定向”理解:在中国官⽅发布的内容越少事也越⼤, “转发”和“重定向”也是⼀样:字越
少,责任越⼤ 。转发是服务器帮转的,⽽重定向是让浏览器重新请求另⼀个地址。
forward 和 redirect 具体区别如下:
1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
2. 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
3. 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。

使用forward不会改变url

 

使用redirect会改变url。