spring mvc学习

本篇是对spring mvc的学习


什么是spring mvc

官方对于 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 构建的

MVC 的定义

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

在这里插入图片描述
Model(模型):是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
View(视图):是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
Controller(控制器):是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,
控制用户输⼊,并向模型发送数据。

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

现在绝⼤部分的 Java 项⽬都是基于 Spring(或 Spring Boot)的,而 Spring 的核心就是 Spring MVC。

学习MVC

学习 Spring MVC 我们只需要掌握以下 3 个功能:

  1. 连接的功能:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的Spring 程序。
  2. 获取参数的功能:用户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
  3. 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给用户。

对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了Spring MVC.

Spring mvc项目的创建

在这里插入图片描述

Spring mvc项目的连接

实现路由链接@RequestMapping
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之⼀,它是用来注册接口的路由映射的。

@Controller// 让 spring 框架启动时,加载
@ResponseBody// 返回⾮⻚⾯数据
@RequestMapping("/user") // 路由器规则注册,可以是一级路由也可以是N级路由
public class UserController {
    @RequestMapping("/sayhi")
    public String sayhi(){
        return "hi spring mvc";
    }
}

@RequestMapping可以设置参数来规定http请求

@RequestMapping(value = "/sayhi",method = RequestMethod.POST)//规定只能是post请求

这样使用get方法会造成405,方法不被允许
在这里插入图片描述

@PostMapping

@PostMapping("sayhello")//只支持post方式

@GetMapping

@GetMapping("sayhello")//只支持get方式

获取参数

获取单个参数,直接在方法后面写形参内容

在这里插入图片描述

@RequestMapping(value = "/sayhi")
    public String sayhi1(String name){//如果为空,会显示默认值null
        return "hi spring mvc"+name;
    }
    @RequestMapping(value = "/sayhi1")
    public String sayhi2(Integer id){//如果为空,会显示默认值null,是包装类型,默认是null
        return "hi spring mvc"+ id;
    }
    @RequestMapping(value = "/sayhi2")
    public String sayhi3(int id){//如果为空,会报错,是基本类型,为空会出错
        return "hi spring mvc"+ id;
    }

使用的名称与前端传递的名称相同
由此可以得出结论:
参数传递不要使用基础数据类型->为空时会报错

获取http

@RequestMapping("/sayhi4")
    public String sayhi4(HttpServletRequest request, HttpServletResponse response){
        return "hi" + request.getParameter("name");
    }

获取多个参数

可以设置多个参数,并且不受顺序影响,使用的名称与前端传递的名称相同

@RequestMapping("/sayhi5")
    public String sayhi5(String name,String password){
        return "name:"+name+"|password"+password;
    }

获取对象(传递)

获取对象可以直接使用此方法

框架会自动实现参数映射,并且会根据返回的数据类型,决定最终响应返回的数据类型

@RequestMapping("/sayhi5")
    public Object user(Userinfo userinfo){
        System.out.println(userinfo);
        return userinfo;
    }

后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,比如前端传递了⼀个time 给后端,而后端又是由 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使用 @RequestParam 来重命名前后端的参数值。
@RequestParam:参数重命名,默认设置为必传

@RequestMapping("/reg")
    public Object reg(@RequestParam("username") String name, String password){//重命名,必须传递参数
        return "name:"+name+"|password"+password;
    }

这样传递可以属于未修改前的,返回修改后
但是@RequestParam是设置参数必传,传递的是默认必须需要设置参数,
这时我们可以进行修改

@RequestMapping("/reg")
    public Object reg(@RequestParam(value = "username",required = false) String name, String password){//重命名,必须传递参数
        return "name:"+name+"|password"+password;
    }

required = false会使这个参数成为一个为必传的参数

@RequestBody 接收JSON对象

当我们传递一个JSON对象时,需要使用注解@RequestBody,

@RequestMapping("/reg2")//传递JSON对象
    public Object reg2(@RequestBody Userinfo userinfo){
        return userinfo;
    }

在接受一个JSON对象时,我们可以使用postman进行查看是否可以成功
在这里插入图片描述

从基础的URL中获取参数(不是从URL的参数部分获取参数)

从URL中获取参数使用注解@PathVariable,注解@PathVariable使用后参数会成为必传参数,不传会出错,也可以使用@PathVariable(required = false)成为非必传参数,也可以使用name重命名

@RequestMapping("/reg3/{name}/{pas}")//从基础的url获取参数,这种方法对参数顺序敏感,需要按照顺序传递
    public Object reg3(@PathVariable String name,@PathVariable(required = false,name = "pas") String password){
        return "name"+name+"| password"+password;
    }

@PathVariable->是基础URL里面的参数(?之前的参数)
@RequestParm->URL参数部分的参数(?之后的参数)

上传文件的功能@RequestPart

使用注解@RequestPart确定key的名字,创建对象接收文件,

@RequestMapping("/reg4")
    public Object reg4(@RequestPart("myimg")MultipartFile file){
        File saverFile = new File("D:\\JAVA\\my.png");
        try {
            file.transferTo(saverFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

在这里插入图片描述
如果图片太大可以在全局配置文件中设置:

spring.servlet.multipart.max-file-size=100MB

但是出现文件覆盖,后面下载的文件会覆盖前面的文件
可以使用UUID保证数据不会覆盖

@RequestMapping("/reg4")
    public Object reg4(@RequestPart("myimg")MultipartFile file){
        String fileName = UUID.randomUUID() +//文件名
                file.getOriginalFilename().substring(//文件后缀。截取文件从.以后开始的后缀
                        file.getOriginalFilename().lastIndexOf("."));
        File saverFile = new File("D:\\JAVA\\"+fileName);
        try {
            file.transferTo(saverFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

获取Cookie/Session/header

获取Reauest和Response对象

@RequestMapping("/cookie")
public String param(HttpServletResponse response, HttpServletRequest request) {
	String name = request.getParameter("name");
 	// 获取所有 cookie 信息
 	Cookie[] cookies = request.getCookies();
 	return name + " 你好";
}

传统获取 header/cookie

@RequestMapping("/cookie")
@ResponseBody
public String param(HttpServletResponse response, HttpServletRequest request) {
	String name = request.getParameter("name");
 	// 获取所有 cookie 信息
 	Cookie[] cookies = request.getCookies();
 	String userAgent = request.getHeader("User-Agent");
 	return name + ":"+userAgent;
}

简洁的获取 Cookie使用@CookieValue注解

@RequestMapping("/reg5")
    public Object getCk(@CookieValue(value = "java",required = false) String java){
        return java;
    }

同样使用了注解@CookieValue,会成为必传参数,可以使用required = false进行设置成非必要参数

简洁获取 Header使用@RequestHeader

Header响应头

@RequestMapping("/getheader")
    public Object getHeader(@RequestHeader("User-header") String header){
        return header;
    }

Session 存储和获取

Session存储
Session获取可以使用注解@SessionAttribute

/*Session 存储和获取*/
    /*Session存储*/
    private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
    @RequestMapping("/setsession")
    public void doPostConstruct(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute(SESSION_KEY,"zhangsan");
    }
    /*Session获取*/
    @RequestMapping("/getsession")
    public Object getSession(@SessionAttribute(SESSION_KEY),String name){
        return "session="+name;
    }

将数据返回前端

返回数据三大类

  1. 返回静态页面
  2. 返回一个非静态页面的数据
  3. 返回一个跳转的地址

返回静态页面

@Controller
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/index")
    public Object test(){
        return "/index.html";
    }
}

返回一个非静态页面的数据

使用@Response注解

返回一个跳转的地址(请求转发或请求重定向)

forward 和 redirect

return 不但可以返回⼀个视图,还可以实现跳转,跳转的方式有两种:
forward 是请求转发;
redirect:请求重定向

// 请求重定向
@RequestMapping("/index")
public String index(){
 	return "redirect:/index.html";
}
// 请求转发
@RequestMapping("/index2")
public String index2(){
 	return "forward:/index.html";
}

请求转发和请求重定向的区别

字越少事越多,请求转发帮着转发,请求重定向告诉你自己去转发

  1. 定义不同
    请求转发(Forward):发生在服务端程序内部,当服务器端收到一个客户端的请求之后,会先将请求,转发给目标地址,再将目标地址返回的结果转发给客户端。
    请求重定向(Redirect):请求重定向指的是服务器端接收到客户端的请求之后,会给客户端返回了一个临时响应头,这个临时响应头中记录了,客户端需要再次发送请求(重定向)的 URL 地址,客户端再收到了地址之后,会将请求发送到新的地址上,这就是请求重定向。
  2. 跳转方不同
    请求转发是服务器端的行为,服务器端代替客户端发送请求,并将结果返回给客户端;
    而请求重定向是客户端的行为,
  3. 数据共享不同
    请求转发是服务器端实现的,所以整个执行流程中,客户端(浏览器端)只需要发送一次请求,因此整个交互过程中使用的都是同一个 Request 请求对象和一个 Response 响应对象,所以整个请求过程中,请求和返回的数据是共享的;而请求重定向客户端发送两次完全不同的请求,所以两次请求中的数据是不同的。
  4. 最终 URL 地址不同
    请求转发是服务器端代为请求,再将结果返回给客户端的,所以整个请求的过程中 URL 地址是不变的;而请求重定向是服务器端告诉客户端,“你去另一个地访问去”,所以浏览器会重新再发送一次请求,因此客户端最终显示的 URL 也为最终跳转的地址,而非刚开始请求的地址,所以 URL 地址发生了改变。
  5. 代码实现不同

forward 和 redirect 具体区别如下

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
  2. 请求重定向地址发生变化,请求转发地址不发生变化。
  3. 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值