• SpringMVC基础


    SpringMVC基础

    SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。

    MVC理论基础

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

    image-20231114162033705

    1. View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源
    2. Model(模型)是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分
    3. Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图,⽤来连接视图和模型

    Spring在实现MVC时,也结合⾃⾝项⽬的特点,做了⼀些改变:

    image-20231114162345211

    学习SpringMVC重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互

    主要分以下三个⽅⾯:

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

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

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

    第一个SpringMVC程序

    在SpringMVC中使⽤ @RequestMapping 来实现URL路由映射

    创建⼀个UserController类:

    @RestController
    public class HelloController {
        @ResponseBody
        @RequestMapping("/")
        public String hello() {
            return "Hello,world";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    效果:

    image-20231116164547448

    请求

    @RequestMapping

    @RequestMapping 是⽤来注册接⼝的路由映射的

    当⽤⼾访问⼀个URL时,将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射

    @RequestMapping即可修饰类,也可以修饰⽅法:

    1. @RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
    2. @RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息
    3. 当修饰类和⽅法时,访问的地址是类路径+⽅法路径

    注意:

    1. @RequestMapping 的URL路径也可以是多层路径
    2. @RequestMapping的URL路径最前⾯加不加 / (斜杠)都可以,Spring程序启动时,如果前⾯没有加会拼接上 /
    3. @RequestMapping 既⽀持Get请求,⼜⽀持Post请求,也⽀持其他的请求⽅式

    指定GET/POST⽅法类型:

    @RequestMapping(value = "/getRequest",method= RequestMethod.GET)
    @RequestMapping(value = "/postRequest",method= RequestMethod.POST)
    
    • 1
    • 2

    传递单参

    接收单个参数,在SpringMVC中直接⽤⽅法中的参数就可以

    @RestController
    public class HelloController {
        @ResponseBody
        @RequestMapping("/")
        public String hello(String name) {
            return "Hello,world"+name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20231116171548864

    注意:

    1. 使⽤基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误;类型不匹配时,会报400错误
    2. 对于包装类型,如果不传对应参数,Spring接收到的数据则为null
    3. 对于参数可能为空的数据,建议使⽤包装类型

    传递多参

    和接收单个参数⼀样,直接使⽤⽅法的参数接收即可

    @RestController
    public class HelloController {
        @ResponseBody
        @RequestMapping("/")
        public String hello(String name,int age) {
            return "Hello,world"+name+age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20231116172003297

    注意:

    前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果

    传递对象

    如果参数⽐较多时,⽅法声明就需要有很多形参,并且后续每次新增⼀个参数,也需要修改⽅法声明,这样不利于代码的维护
    可以将这些参数封装为⼀个对象,SpringMVC可以⾃动实现对象参数的赋值

    @Data
    public class Person {
        String name;
        String sex;
        int age;
    }
    @RestController
    public class HelloController {
        @ResponseBody
        @RequestMapping("/")
        public String hello(Person person) {
            return "Hello,world person:"+ person.getName()+person.getAge()+person.getSex();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    image-20231116172637747

    注意:

    Spring会根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,⽐如int类型的属性,会被赋值为0)

    传递数组和集合

    SpringMVC可以⾃动绑定数组参数的赋值

    @RequestMapping("/m2")
    public String m2(String[] str) {
        return "Hello,world str:"+ Arrays.toString(str);
    }
    
    • 1
    • 2
    • 3
    • 4

    image-20231116190946583

    集合参数:和数组类似,需要使⽤ @RequestParam 绑定参数关系

    默认情况下,请求中参数名相同的多个值,是封装到数组;如果要封装到集合,要使⽤@RequestParam 绑定参数关系

    @RequestMapping("/m3")
    public String m3(@RequestParam List<String> str) {
        return "Hello,world str:"+ str;
    }
    
    • 1
    • 2
    • 3
    • 4

    传递JSON数据

    JSON的语法:

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

    JSON优点:

    1. 简单易⽤:语法简单,易于理解和编写,可以快速地进⾏数据交换
    2. 跨平台⽀持:JSON可以被多种编程语⾔解析和⽣成,可以在不同的平台和语⾔之间进⾏数据交换和传输
    3. 轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占⽤带宽较⼩,可以提⾼数据传输速度
    4. 易于扩展:JSON的数据结构灵活,⽀持嵌套对象和数组等复杂的数据结构,便于扩展和使⽤
    5. 安全性:JSON数据格式是⼀种纯⽂本格式,不包含可执⾏代码,不会执⾏恶意代码,因此具有较⾼的安全性

    基于以上特点,JSON在Web应⽤程序中被⼴泛使⽤,如前后端数据交互、API接⼝数据传输等

    接收JSON对象,需要使⽤ @RequestBody 注解:

    @RequestMapping("/m4")
    public String m4(@RequestBody Person person) {
        return "Hello,world person:"+ person;
    }
    
    • 1
    • 2
    • 3
    • 4

    image-20231116195517241

    @RequestParam

    前端传递的参数key和我们后端接收的key可以不⼀致,可以使⽤ @RequestParam 来重命名前后端的参数值,进行构建映射关系

    @ResponseBody
    @RequestMapping("/m1")
    public String m1(@RequestParam("name") String str) {
        return "Hello,world name:"+ str;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:

    1. 使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称⼀致,才能进⾏参数绑定和赋值
    2. 使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数

    分析注解:

    @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";//默认数值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    设置非必传参数:

    @RequestMapping("/m1")
    public String m1(@RequestParam(value = "name",required = false) String str) {
        return "Hello,world name:"+ str;
    }
    
    • 1
    • 2
    • 3
    • 4

    @PathVariable

    pathvariable:路径变量
    和字⾯表达的意思⼀样,这个注解主要作⽤在请求URL路径上的数据绑定

    @RequestMapping("/m5/{name}/{id}")
    public String m5(@PathVariable Integer id, @PathVariable("name") String username) {
        return "Hello,world person:"+ id+username;
    }
    
    • 1
    • 2
    • 3
    • 4

    image-20231116195916263

    如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时,可以简写,不⽤给@PathVariable的属性赋值,否则需要@PathVariable的属性value赋值

    @RequestPart

    上传⽂件使用@RequestPart 注解

    @RequestMapping("/m6")
    public String m6(@RequestPart MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        file.transferTo(new File("C:\\Users\\HP\\Desktop\\"+fileName));
        return "接收文件名称:"+fileName;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    image-20231116202352915

    Cookie/Session

    Cookie和Session的区别:

    1. Cookie是客⼾端保存⽤⼾信息的⼀种机制;Session是服务器端保存⽤⼾信息的⼀种机制
    2. Cookie和Session之间主要是通过SessionId关联起来的;SessionId是Cookie和Session之间的桥梁
    3. Cookie和Session经常会在⼀起配合使⽤,但是不是必须配合
      ◦ 完全可以⽤Cookie来保存⼀些数据在客⼾端这些数据不⼀定是⽤⼾⾝份信息,也不⼀定是SessionId
      ◦ Session中的sessionId也不需要⾮得通过Cookie/Set-Cookie传递,⽐如通过URL传递

    传统获取Cookie:

    @RequestMapping("/m8")
    public String m8(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        StringBuilder builder = new StringBuilder();
        if(cookies!=null) {
            for (Cookie ck:cookies) {
                builder.append(ck.getName()+":"+ck.getValue());
            }
        }
        return "Cookie:"+builder;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    简洁获取Cookie:

    @RequestMapping("/m8")
    public String m9(@CookieValue("test") String test) {
        return "Cookie:"+test;
    }
    
    • 1
    • 2
    • 3
    • 4

    获取Session:

    Session是服务器端的机制,我们需要先存储,才能再获取;Session也是基于HttpServletRequest来存储和获取的

    @RequestMapping("/m9")
    public String m9(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if(session!=null) {
            session.setAttribute("test","hello");
        }
        return "session set";
    }
    @RequestMapping("/m10")
    public String m10(HttpSession session) {
        return "session:"+session.getAttribute("test");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image-20231116211419448

    说明:

    1. HttpSession getSession(boolean create):参数如果为true,则当不存在会话时新建会话;参数如果为false,则当不存在会话时返回null
    2. HttpSession getSession():和getSession(true)含义⼀样,默认值为true
    3. void setAttribute(Stringname,Objectvalue):使⽤指定的名称绑定⼀个对象到该session会话
    4. ObjectgetAttribute(Stringname):返回在该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回null

    简洁获取Session:

    @RequestMapping("/m11")
    public String m11(@SessionAttribute(value = "username",required = false) String name) {//获取指定key
        return "session:"+name;
    }
    
    • 1
    • 2
    • 3
    • 4
    public String m10(HttpSession session) {
        return "session:"+session.getAttribute("test");
    }
    
    • 1
    • 2
    • 3

    获取Header

    获取Header也是从 HttpServletRequest 中获取

    @RequestMapping("/param10")
    public String param10(HttpServletRequest request, HttpServletResponse response)
        String userAgent = request.getHeader("User-Agent");
    	return name + ":"+userAgent;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @RequestMapping("/header")
    public String header(@RequestHeader("User-Agent") String userAgent) {
    	return "userAgent:"+userAgent;
    }
    
    • 1
    • 2
    • 3
    • 4

    响应

    Http响应结果可以是数据,也可以是静态⻚⾯,也可以针对响应设置状态码,Header信息等

    返回静态页面

    @Controller
    public class IndexController {
        @RequestMapping("/index")
        public Object index(){
            //返回index.html
            return "/index.html";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    @RestController = @Controller + @ResponseBody

    @Controller :定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理

    @ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息

    如果想返回视图的话,只需要把 @ResponseBody 去掉就可以了,也就是 @Controller

    @ResponseBody

    @ResponseBody 表⽰返回数据

    @ResponseBody 既是类注解,⼜是⽅法注解:

    1. 如果作⽤在类上,表⽰该类的所有⽅法,返回的都是数据,如果作⽤在⽅法上,表⽰该⽅法返回的是数据
    2. 如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注解

    返回HTML代码⽚段

    后端返回数据时,如果数据中有HTML代码,也会被浏览器解析

    响应中的Content-Type常⻅取值有以下⼏种:

    1. text/html:body数据格式是HTML
    2. text/css:body数据格式是CSS
    3. application/javascript:body数据格式是JavaScript
    4. application/json:body数据格式是JSON

    如果请求的是js⽂件,SpringMVC会⾃动设置Content-Type为 application/javascript

    如果请求的是css⽂件,SpringMVC会⾃动设置Content-Type为 text/css

    返回JSON

    SpringMVC也可以返回JSON,后端⽅法返回结果为对象

    @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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    image-20231116213323566

    设置状态码

    SpringMVC会根据我们⽅法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码

    通过SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

    @RequestMapping(value = "/setStatus")
    @ResponseBody
    public String setStatus(HttpServletResponse response) {
        response.setStatus(401);
        return "设置状态码成功";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    状态码不影响⻚⾯的展⽰

    设置Header

    Http响应报头也会向客⼾端传递⼀些附加信息,⽐如服务程序的名称,请求的资源已移动到新地址等,如:Content-Type,Local等

    通过 @RequestMapping 注解的属性来实现

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Mapping
    public @interface RequestMapping {
        String name() default "";
        @AliasFor("path")
        String[] value() default {};
        @AliasFor("value")
        String[] path() default {};
        RequestMethod[] method() default {};
        String[] params() default {};
        String[] headers() default {};
        String[] consumes() default {};
    	String[] produces() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    说明:

    1. value:指定映射的URL
    2. method:指定请求的method类型,如GET,POST等
    3. consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json,text/html;
    4. produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
    5. Params:指定request中必须包含某些参数值时,才让该⽅法处理
    6. headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求

    设置Content-Type

    通过设置produces属性的值,设置响应的报头Content-Type

    @RequestMapping(value = "/returnJson2",produces = "application/json")
    @ResponseBody
    public String returnJson2() {
    	return "{\"success\":true}";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果不设置produces,⽅法返回结果为String时,SpringMVC默认返回类型,是text/html

    设置响应编码

    @RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
    @ResponseBody
    public String returnJson2() {
        return "{\"success\":true}";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    设置其他Header

    使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

    @RequestMapping(value = "/setHeader")
    @ResponseBody
    public String setHeader(HttpServletResponse response) {
    response.setHeader("MyHeader","MyHeaderValue");
        return "设置Header成功";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值
    返回类型,是text/html

    设置响应编码

    @RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
    @ResponseBody
    public String returnJson2() {
        return "{\"success\":true}";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    设置其他Header

    使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

    @RequestMapping(value = "/setHeader")
    @ResponseBody
    public String setHeader(HttpServletResponse response) {
    response.setHeader("MyHeader","MyHeaderValue");
        return "设置Header成功";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值

  • 相关阅读:
    Java 创建线程的方法
    莱卡公司在多恩比恩全球纤维大会上推广近期的创新
    Gopsutil/Process常用进程监控资源信息
    1039 Course List for Student
    Python编程 元组中不允许的操作
    Springboot毕设项目旅游助手系统wp1hv(java+VUE+Mybatis+Maven+Mysql)
    SAP MM会计凭证凭证状态为U
    docker安装和info信息
    跨越边界:虚拟直播间席卷各行业领域,引爆下一代直播风暴
    mac 安装cnpm 淘宝镜像记录
  • 原文地址:https://blog.csdn.net/CS_z_jun/article/details/134477427