Spring Web MVC入门

news2024/11/15 8:30:08

一:了解Spring Web MVC

(1)关于Java开发

🌟Java开发大多数场景是业务开发


比如说京东的业务就是电商卖货、今日头条的业务就推送新闻;快手的业务就是短视频推荐

(2)Spring Web MVC的简单理解

💗Spring Web MVC:如何使用Spring去建网站

(我们知道既然Java是做业务开发就避免不了建网站)


💗 Spring Web MVC是⼀个Web框架;也可以简称为Spring MVC 

①Spring:Spring就是一个框架,能让我们更快速、便捷和高效的去完成Java开发


②Web:表示做的是网页、网站的开发


③MVC:MVC是Model View Controller的缩写,它是软件工程中的一种软件架构设计模式

(MVC就是把项目分为模型、视图和控制器三个基本部分 )

二:学习Spring Web MVC前提

(1)了解客户端和服务器的交互

💗通过客户端和服务器进行交互主要分为三个方面

(客户端:浏览器/用户程序)


①建立连接:将客户端(浏览器/用户程序)和服务器(Java程序)连接起来,也就是访问⼀个浏览器地址能够调用到我们Java写的的Spring程序


②请求:当建立完连接之后,客户端会向服务器发出一个请求,此时在服务器端就得获取到请求的参数;因此,总的来说请求这块的主要是服务器为了获取请求的参数


③响应:服务器获取请求参数后,然后执行业务逻辑,执行完毕就把执行的结果返回给客户端


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

(2)项目准备

🌟Spring MVC项目创建和SpringBoot创建项目相同,在创建的时候选择Spring Web就相当于创建了Spring MVC的项目

三:Spring Web MVC-建立连接

(1)@RequestMapping概念

①作用:实现URL路由映射,也就是实现客户端连接服务器的作用

(即浏览器连接Java后端它们通过@RequestMapping建立连接)


②访问:IP:端口号/类的路径+方法路径

(类的路径和方法路径其实就是@RequestMapping里的参数;区分方式主要看它写在类外还是类内)


③理解:表示服务器收到请求时,路径为XXX的请求就会调用XXX路径对应这个方法的代码

(2)@RequestMapping使用方式

1.使用方式和细节

💗@RequestMapping既可以修饰类,也可以修饰方法


🌟@RequestMapping参数里的“/”可以省略,但还是建议加上

2.方法路径

💙方法路径:写在类内;此时如果没有类的路径直接通过方法路径即可访问网址


🖤下列代码表示服务器收到请求时,路径为/sayhi的请求就会调用sayHi这个方法里的代码

package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//此时没有类的路径,那么类的路径就为空,直接访问方法路径即可
@RestController
public class HelloController {
    @RequestMapping("/sayhi")    //方法路径
    //sayHi()方法就是需要在网站上显示什么;方法名不要求与路径名相同
    //例如我的路径名是sayhi,方法名是sayHi
    public String sayHi() {    
        return "hi,SpringBoot";
    }
}

3.类的路径

💙类的路径:写在类外;此时需要通过类的路径+方法路径才能访问网址


package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RequestMapping("/hlizoo")    //类路径
@RestController
public class HelloController {
    @RequestMapping("/sayhi")    //方法路径
    public String sayHi() {
        return "hi,SpringBoot";
    }
}

4.路径嵌套

💙路径也可以包含多层,即多层套娃


package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RequestMapping("/hlizoo/cool")    //类路径;多层路径
@RestController
public class HelloController {
    @RequestMapping("/sayhi/no")    //方法路径;多层路径
    public String sayHi() {
        return "hi,SpringBoot";
    }
}

(3)@RequestMapping限制请求

 💗@RequestMapping支持所有的请求,比如GET、POST、PUT等等


🌟@RequestMapping如果没有写属性,默认只有路径,此时可以写Method属性来限制请求的方法

(比如以下代码:说明路径是/hlizoo/sayhi和请求方法是GET时才调用sayHi方法)

package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/hlizoo")    //类路径
@RestController
public class HelloController {
    //当你写了mehod,前面的路径就会默认加上value
    @RequestMapping(value = "/sayhi",method = RequestMethod.GET)    //方法路径;此时指定是GET请求
    public String sayHi() {
        return "hi,SpringBoot";
    }
}

四:Spring Web MVC-请求

(1)明确请求部分的学习内容

💗学习Spring的请求,主要是学习如何传递参数到后端(服务器)以及后端(服务器)如何接收


💚原因就是当我们访问不同的路径,就会发送不同的请求,在发送请求时,可能会带⼀些参数,我们就要学习如何传参和接参

(2)传递单个参数的接收方法

1.方法

💗方法:接收单个参数,直接在Spring MVC的方法形参中声明参数数据类型和参数名即可


💛参数类型建议使用包装数据类型

(1)如果传的是基本数据类型,必须要传参传值,否则会报错

(2)如果传的是包装数据类型,不传参传值不会报错,而是返回null

2.后端代码
package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m1")
    //此时就代表了接收了一个name参数
    //至于这个name前端是如何给的,作为后端人员并不关心,我的要求只是一个name参数而已
    //接收单个参数,直接在m1方法写参数数据类型和参数名即可
    public String m1(String name){
        return "接收到的参数name:"+name;
    }
}
3. 利用Postman发送单个参数的请求

①当没有传递name参数的情况


②当传递了name参数的情况

4.注意事项

(3)传递多个参数的接收方法

1.方法

💗方法:接收多个参数,直接在Spring MVC的方法形参中声明多个参数数据类型和参数名即可


💛参数类型建议使用包装数据类型

(1)如果传的是基本数据类型,必须要传参传值,否则会报错

(2)如果传的是包装数据类型,不传参传值不会报错,而是返回null

2.后端代码
package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/param")
@RestController
public class ParamController {
    //接收多个参数,直接在m2方法写多个参数数据类型和参数名即可
    @RequestMapping("/m2")
    public String m2(String name,Integer age){
        return "接收到的参数name:"+name+",age:"+age;
    }
}
3. 利用Postman发送多个参数的请求

4.注意事项

 

(4)传递对象的接收方法

1.方法

💗方法

①先写一个类,把这些参数封装为一个对象,写上Getter和Setter以及toString方法

②在方法的形参部分写上类和对象名


(原因:当参数过多时,方法声明就要写很多的形参,形参太多既不雅观修改也不方便,不妨写个类封装成对象)

2.后端代码

①新建一个Person类

package com.example.demo;

public class Person {
    Integer id;
    String name;
    Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

②方法的代码

package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m4")
    public String m4(Person person){
        return "接收到的参数person:"+person.toString();
    }
}
 3.利用Postman发送请求

(5)后端参数重命名

1.方法

💗方法:@RequestParam来重命名前后端的参数值


①进行了重命名后,就一定要使用@RequestParam里写的名字来进行传参

②进行了重命名后,如果使用了其他名字来进行传参,要么报错要么为null

2.后端代码

🖤情况:某些特殊的情况下,前端传递的参数key和我们后端接收的key可以不一致

比如后端是使用username字段来接收的,而前端却用了name字段来传递,这样就会出现参数接收不到的情况


package com.example.demo.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m5")
    public String m5(@RequestParam("name") String username){
        return "接收到的参数name:"+username;
    }
}
3. 利用Postman发送请求

①当用name作为字段来传参时,可以顺利的接收到请求


②当用username作为字段传参的时候,反而报错了

4.注意事项

💓①如果使用了@RequestParam且不加任何属性,那么它里面的参数就是必传参数了,如果使用了其它的字段来传参就会报错


💓(2)@RequestParam里如果添加了required属性,required为false则里面的参数就不是必传参数了,使用了其他字段传参不会报错只会变成null

(6)传递数组的接收方法

1.方法

💗方法:在方法形参中写个数组即可;因为Spring MVC可以自动绑定数组参数的赋值


💛当我们的请求中,同一个参数名的参数有多个时,浏览器会给我们封装成一个数组

2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m6")
    public String m6(String []arrayParam){
        return "接收到的参数arrayParam:"+ Arrays.toString(arrayParam);
    }
}
3.利用浏览器发送请求

🌟方式一:用浏览器发送多个相同参数名的参数,参数之间用&分割

(当请求中同一个参数名arrayParam的参数有多个时,浏览器会给我们封装成一个数组)


🌟方式二:用浏览器发送多个相同参数名的参数,参数之间用,分割

(当请求中同一个参数名arrayParam的参数有多个时,浏览器会给我们封装成一个数组)

(7)传递集合的接收方法

1.方法

💗方法:先使用@RequestParam绑定参数关系,然后写集合类和对象名即可


💛集合接收的方法和数组类似,只不过在默认情况下,请求中参数名相同的多个值,是封装到数组;如果要封装到集合,要使用@RequestParam绑定参数关系

2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;


@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m7")
    public String m7(@RequestParam List<String> listParam){
        return "接收到的参数listParam:"+ listParam + "长度为:"+listParam.size();
    }
}
3.利用Postman发送请求

 (8)传递JSON数据的接收方法

1.JSON定义

JSON:JavaScriptObjectNotation 【JavaScript对象表示法】


💓①JSON就是⼀种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息


💓②JSON本质是字符串;主要负责在不同的语言中数据传递和交换

2.JSON语法



3.JSON字符串和Java对象互转

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


①writeValueAsString: 把Java对象转为JSON字符串

(参数写的是Java对象)


②readValue: 把JSON字符串转为Java对象

(第一个参数是JSON字符串;第二个参数是Java对象)


public class JSONUtils {
 private static ObjectMapper objectMapper = new ObjectMapper();

 public static void main(String[] args) throws JsonProcessingException {
       Person person = new Person();
       person.setId(5);
       person.setName("zhangsan");
       person.setPassword("123456");
       //Person对象转为JSON字符串
       String jsonStr = objectMapper.writeValueAsString(person);
       System.out.println("JSON字符串为:"+jsonStr);
       //JSON字符串转为对象
       Person p = objectMapper.readValue(jsonStr,Person.class);
       System.out.println("转换的对象    
       id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
 }
}
 
4.方法

💗方法:接收JSON对象,需要使用@RequestBody注解


🌟RequestBody:请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须写在请求正文中

5.后端代码

①创建一个Person对象

package com.example.demo;

public class Person {
    Integer id;
    String name;
    Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

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

②方法的代码

package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m8")
    public String m8(@RequestBody Person person){
        return "接收到的数据person:"+person.toString();
    }
}
6.利用Postman发送JSON请求

(9)获取URL中的参数

1.方法

💗方法:使用到@PathVariable来拿到URL的参数


💛@PathVariable主要作用在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到

2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController { 
    //注意@RequestMapping的参数
    @RequestMapping("/m9/{userId}")
    public String m9(@PathVariable Integer userId)  {
        return "userId:"+userId;
    }
}
3.利用Postman发送请求

4.注意事项

(10)上传文件

1.方法

💗方法:使用到@RequestPart


①文件我们一般用MultipartFile file来接收,因此方法的形参一般写@RequestPart MultipartFile file


②transferTo方法可以将文件上传且保存到指定路径

2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m10")
    public String m10(@RequestPart MultipartFile file) throws IOException {
        //获取文件名称
        String filename = file.getOriginalFilename();
        //上传文件到指定路径
        file.transferTo(new File("D:/test/"+file.getOriginalFilename()));
        return "success,"+"文件名称:"+filename;
    }
}

3.利用Postman发送图片请求


4.注意事项

(11)获取Cookie/Session

1.为什么会出现Cookie与Session

💗原因:HTTP协议自身是属于"无状态"协议,即HTTP协议无记忆功能


💙"无状态"的含义指的是:默认情况下HTTP协议的客户端和服务器之间的这次通信,和下次通信之间没有直接的联系;但是实际开发中,我们很多时候是需要知道请求之间的关联关系的, 例如登录网站成功后,第⼆次访问的时候服务器就能知道该请求是否是已经登陆过了

2.区分Cookie与Session概念

 ①Cookie是浏览器存储(临时)数据的机制


②Session是服务器存储(临时)数据的机制

(作用:存储用户的详细信息;并给用户分配一个唯一值sessionid;后续再访问网站的其他页面时,HTTP请求就会自动带上sessionid,通过sessionid就能找到对应的Session即对应的用户)


③两者的区别


④两者的联系

3.详解Cookie

①Cookie是浏览器本地存储数据的一种机制

💜(此时在服务器这边就需要记录"令牌"信息,以及令牌对应的用户信息,这个就是Session机制所做的工作;下文详细说)


②作用:实现 "身份标识" 的功能;每个不同的域名下都可以有不同的Cookie, 不同网站之间的Cookie并不冲突

🌟(Cookie会存储很多键值对,往往会有一个很重要的键值对是用来表示用户的“身份信息”,即标识当前请求是来自于哪个用户的;就会产生这么一种场景,比如你登陆一个网站,后续再访问这个网站页面,就无需登录了,而且就算关了电脑,第二天重开网页,依然不需要登录)


③Cookie的原理:Cookie是按键值对的形式来存储了一些字符串,这些键值对往往都是由服务器返回回来的,浏览器把这些键值对按照“域名”维度进行分类存储,意思就是说不同网站就有不同的Cookie,例如百度有百度的Cookie,搜狗有搜狗的Cookie,这些Cookie的内容都是由程序猿自己定义的


④Cookie的保存机制:


⑤总结:

(1)Cookie从哪来?

答:Cookie是从服务器返回给浏览器的

(2)Cookie是如何保存的?保存在哪?

答:浏览器按照不同的域名分别存储Cookie,域名与域名之间的Cookie是不能互相干扰的,即每一组域名都有自己的Cookie;Cookie保存在浏览器所在电脑的硬盘上,就算关机也不会影响到

(3)Cookie中的内容是啥?

答:Cookie中的内容是键值对结构的数据,这里的键值对是由程序猿自己定义的

(4)Cookie中的内容到哪里去?

答:后续访问该网站的各个页面时,就都会在请求中带上Cookie,服务器就可以进一步知道客户端用户的详细情况 


⑥Cookie的缺点:

🌟Cookie是可以伪造的


🌟问:浏览器要保存数据为啥要先保存到Cookie再让Cookie保存到硬盘,而不能直接往硬盘写入一个文件保存?

答:往硬盘写入是绝对不行的!因为如果你让网页能够轻易的访问你的文件系统,这是一件非常危险的事情;想一下如果你上一种病毒网站,网站直接给你的电脑上下个病毒或者直接把你硬盘上已有的数据删除掉了,那不就完蛋了?

💓因此为了保证安全,浏览器会对网页的功能作出限制,禁止访问硬盘就是对网页的其中一个限制;所以为了既能保证安全也能保存数据,浏览器就提供了一个Cookie功能!

4.了解Session

 🌟①Sessionid保存在Cookie中,后面再去访问服务器的时候,我的Cookie就带着Sessionid去访问,然后服务器就可以根据这个Sessionid去返回对应的Session了

(但在服务器这边也需要记录SessionId,以及SessionId对应的用户信息Session)


🌟②Session的缺点:存在分布式问题


5.获取Cookie的普通方法

💗普通方法:需要用到HttpServletRequest,HttpServletResponse,它们是Servlet提供的两个类


💚①HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息


💚②HttpServletResponse对象代表服务器的响应,HTTP响应的信息都在这个对象中,比如向客户端发送的数据、响应头、状态码等;通过这个对象提供的方法,可以获得服务器响应的所有内容


🌟这两个类是Spring内置的对象,当你需要的时候,直接在方法声明加上即可

6.获取Cookie的后端代码(普通版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getcookie")
    public String m11(HttpServletRequest request, HttpServletResponse response){
         //拿到cookie的对象
        Cookie[] cookies = request.getCookies();
        //打印cookie的值
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName()+":"+cookie.getValue());
            } 
        }
        return "获取cookie成功!";
    }
}
7.获取Cookie的简单方法

💗简单方法:使用@CookieValue即可


🌟使用简单的方法一个@CookieValue一次只能拿一个Cookie,要想拿多个Cookie,就得使用多个@CookieValue

💚(它不像普通方法那样一次性可以拿完全部的Cookie然后保存到数组中)

8.获取Cookie的后端代码(简单版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getcookie2")
    public String m12(@CookieValue String bite,@CookieValue String aaa){
        return "cookie存储的值bite:"+bite+",aaa:"+aaa;
    }
}
9.利用浏览器设置Cookie(普通版)

①右键浏览器,选择检查,选择Applicaition


②选择左侧栏Storage栏中的Cookies


③自主添加Name和Value,比如我添加如下图所示的


④此时再次刷新网页并观看IDEA控制台

10.利用浏览器设置Cookie(简单版)

💛当设置好Cookie后,直接就可以获取了

11.获取Session的普通方法

💗普通方法①:基于HttpServletRequest来存储和获取的


💗普通方法②:基于HttpSession来存储和获取的
HttpServletRequest、HttpServletResponse、HttpSession都是Spring内置对象

(内置对象:需要使用的时候直接方法声明即可)


🌟Session是服务器端的机制,我们需要先存储,才能再获取

12.获取Session的后端代码(普通版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {  
    //session要先存储才能获取;并且session不像cookie那样可以设置
    //这里先存储session
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("username","zhangsan");
        return "success";
    }
     
    //第一种普通方法:使用Spring内置对象HttpServletRequest
    @RequestMapping("/getsession")
    public String m13(HttpServletRequest request){
        //参数为true,没有session则创建session
        //参数为false,没有session则放回null
        HttpSession session = request.getSession(false);
        if (session!=null){
            String username = (String) session.getAttribute("username");
            return "登录用户:"+username;
        }
        return "session为空"; 
    }

    //第二种普通方法:使用Spring内置对象HttpSession
    @RequestMapping("/getsession3")
    public String m15(HttpSession session){
       String username = (String) session.getAttribute("username");
       return "登录用户:"+username;
    }
}
13.观察浏览器(普通版)

①先输入setSession来观察浏览器效果

(因为session要先存储才能获取)


②再去观察Cookie的效果,可以看到多了一个JSESSIONID

14.获取Session的简单方法

💗方法:使用@SessionAttribute即可


🌟使用简单的方法一个@SessionAttribute一次只能拿一个Session,要想拿多个Session,就得使用多个@SessionAttribute


🌟使用@SessionAttribute的参数默认是必传参数,如果让required=false,就不是必传参数了

15.获取Session的后端代码(简单版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    //session要先存储才能获取;并且session不像cookie那样可以设置
    //这里先存储session
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("username","zhangsan");
        return "success";
    }

    @RequestMapping("/getsession2")
    public String m14(@SessionAttribute(required = false) String username){
        return "username:"+username;
    }
}
16.观察浏览器(简单版)

①依旧是输入先输入setSession来观察浏览器效果

(因为session要先存储才能获取)


②此时去观察简单方法的浏览器效果

(12)获取Header

1.获取Header的普通方法

💗普通方法:依旧使用内置对象HttpServletRequest,通过HttpServletRequest提供的getHeader方法来获取,参数对应HTTP请求报头的"Key"

2.后端代码(普通版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getHeader")
    public String m16(HttpServletRequest request){
        String UserAgent = request.getHeader("User-Agent");
        return "User-Agent:"+UserAgent;
    }
}
3.观察浏览器效果(普通版)

4.获取Header的简单方法

💗简单方法:使用@RequestHeader;@RequestHeader的参数值为HTTP请求报头中的"Key",如果你想赋值给哪个变量,在后面写上即可

5.后端代码(简单版)
package com.example.demo.Controller;
import com.example.demo.Person;
import com.sun.deploy.net.HttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@RequestMapping("/param")
@RestController
public class ParamController {  
@RequestMapping("/getHeader2")
    public String m17(@RequestHeader("User-Agent") String UserAgent){
        return "User-Agent:"+UserAgent;
    }
}
6.观察浏览器效果(简单版)

五:Spring Web MVC-响应

(1)返回静态页面

1.方法

💗方法:使用的是@Controller

(不是@RestController,跟上述的请求不一样,下文详细分析)


💚返回static目录下的静态页面,直接在return后面加上“/XXX.html”即可

(比如:return "/login.html")

2.前端代码

①先在static目录下创建一个名字为index的html文件


②因为是用来测试的,我们前端代码写得简单一点就行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index首页</title>
</head>
<body>
    <h1>我是index页面</h1>
</body>
</html>

③重新启动服务器,访问index.html看看效果如何

(static目录下的静态页面可直接访问)

3.后端代码
package com.example.demo.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller
public class ReturnController {
    @RequestMapping("/index")
    public String returnIndex(){
        return "/index.html";
    }
}
4.观察浏览器效果

5.初次了解@RestController

💗①@RestController = @Controller + @ResponseBody

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

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


💗②@Controller返回视图页面;@ResponseBody返回页面的数据


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

6.初次了解@Controller

💗作用:Spring框架启动时加载,把这个对象交给Spring管理;然后去找需要返回的视图,如果找到就返回例如HTML页面等等的视图,没找到就报错404

(即是说把整个代码交给Spring,告诉Spring帮我们去管理;后续我们访问时,才能访问到)


(2)返回数据

1.方法

💗方法:使用的是@ResponseBody;表示返回数据

(比如return "/index.html",@Controller会去查找index.html文件,但是如果加了@ResponseBody,就直接把"/index.html"当做⼀个文本数据返回给前端)


①@ResponseBody既是类注解,又是方法注解


②@ResponseBody如果作用在类上,表示该类的所有方法返回的都是数据

(1)在类上添加@ResponseBody就相当于在所有的方法上添加了@ResponseBody

(2)相同,如果类上有@RestController时,表示所有的方法上添加了@ResponseBody,也就是当前类下所有的方法返回值都为响应数据 


③@ResponseBody如果作用在方法上,表示该方法返回的是数据

2.后端代码
package com.example.demo.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {   
    @ResponseBody   //作用于方法上,表示returnData方法返回的是一个文本数据
    @RequestMapping("/returndata")
    public String returnData(){
        return "/index.html";   //此时加了@ResponseBody,就直接返回一个文本数据
    }
}
3.观察浏览器效果

(3)返回HTML代码片段

1.方法

💗方法:使用@ResponseBody也可返回HTML的文本数据


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

2.后端代码
package com.example.demo.Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {
    @ResponseBody
    @RequestMapping("/returnHTML")
    public String returnHTML(){
        return "<h1>这是一个HTML片段</h1>";
    }
}
3.观察浏览器效果

(4)返回JSON

1.方法

💗方法:使用@ResponseBody;要想返回JSON则返回类型是对象或者Map即可

2.后端代码(示例一)
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {
    @ResponseBody
    @RequestMapping("/returnJSON")
    public Person returnjson(){    //使用之前的Person类
        Person person = new Person();
        person.setId(7);
        person.setName("hlizoo");
        person.setAge(20);
        return person;
    }
}
3.观察浏览器效果(示例一)

4.后端代码(示例二)
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {
    @ResponseBody
    @RequestMapping("/returnMAP")
    public Map<String,String> returnmap(){
        Map<String,String> kv = new HashMap<>();
        kv.put("k1","v1");
        kv.put("k2","v2");
        kv.put("k3","v3");
        return kv;
    }
}
5.观察浏览器效果(示例二)

6.注意事项

①当我们的返回类型是基本数据类型和包装类型时,Content-Type默认是text/html

(比如String、Integer等等)


②当我们的返回类型是对象和Map等等时,Content-Type自动设置为application/json

(只要返回类型是对象和Map时,要想返回json那啥都不用做,浏览器自动就搞好了)

(5)设置状态码

1.方法

💗方法:使用Spring MVC内置对象HttpServletResponse提供的setStatus方法进行设置


💛Spring MVC会根据我们方法的返回结果自动设置响应状态码,当然我们也可以手动指定状态码


💚注意这里的状态码并不影响页面的展示,就算你的状态码是401,也会显示你设置的内容

2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {
    @ResponseBody
    @RequestMapping("/setStatus")
    public String setstatus(HttpServletResponse response){
        response.setStatus(401);
        return "设置状态码";
    }
}
3.观察浏览器效果

(6)设置Content-Type

1.方法

💗方法:通过设置@RequestMapping里produces属性的值,来设置响应的报头Content-Type


2.后端代码
package com.example.demo.Controller;
import com.example.demo.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;


@RequestMapping("/return")
@Controller     //←注意这里用的是Controller,下面如果要返回数据必须要加上@ResponseBody
public class ReturnController {   
    @ResponseBody
    @RequestMapping(value = "/r1",produces = "application/json;charset=utf8")
    public String r1() {
        return "{'ok':200}";
    }
}
3.观察浏览器效果

(7)自行设置Header

💗方法:通过内置对象HttpServletResponse里setHeader方法来设置响应的报头

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetCode 76. 最小覆盖子串 + 滑动窗口 + Hash + 图解(详细)

76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻…

分布估计算法(Estimation of distribution algorithm,EDA)

概论 分布估计算法&#xff08;Estimation of distribution algorithm&#xff0c;EDA&#xff09;是一种新兴的基于统计学原理的随机优化算法。 为什么要叫这个名字呢&#xff1f; 首先&#xff0c;“分布”指的就是概率分布。 其次&#xff0c;“估计”指的是这个概率分布…

2023年【河北省安全员B证】新版试题及河北省安全员B证试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 河北省安全员B证新版试题根据新河北省安全员B证考试大纲要求&#xff0c;安全生产模拟考试一点通将河北省安全员B证模拟考试试题进行汇编&#xff0c;组成一套河北省安全员B证全真模拟考试试题&#xff0c;学员可通过…

C++STL----list的模拟实现

文章目录 list模拟实现的大致框架节点类的模拟实现迭代器类的模拟实现迭代器类存在的意义迭代器类的模板参数说明运算符的重载--运算符的重载&#xff01;与运算符的重载*运算符的重载->运算符的重载 list的模拟实现默认成员函数迭代器相关函数元素修改相关函数front和backi…

“KeyarchOS:国产Linux新星的崛起与创新之路“

简介 KOS&#xff0c;也就是KeyarchOS&#xff0c;是一款由国内团队开发的服务器操作系统。它因为几个特点而受到我的青睐和一些用户的关注。 首先&#xff0c;KOS注重安全性和稳定性。它有一些防护和隔离功能&#xff0c;来帮助系统稳定运行&#xff0c;而且是中文语言更接地…

从零开始的LINUX(三)

bc&#xff1a;进行浮点数运算 uname&#xff1a;查看当前的操作系统 ctrlc&#xff1a;中止当前正在执行的程序 ctrld&#xff1a;退出xshell shutdown&#xff1a;关机 reboot&#xff1a;重启 shell外壳&#xff1a; 作用&#xff1a;1、命令解释&#xff08;将输入的程序…

QSS 自定义QLineEdit

QSS 自定义QLineEdit Chapter1 QSS 自定义QLineEdit简述常用属性和伪状态效果图QSS源码参考 Chapter1 QSS 自定义QLineEdit 原文链接&#xff1a;https://blog.csdn.net/Staranywhere/article/details/107306276 简述 本文将通过简单示例介绍QLineEdit样式如何自定义。 常用…

Linux高性能服务器编程——ch9笔记

第9章 I/O复用 同时监听多个文件描述符&#xff0c;但本身是阻塞的。 9.1 select系统调用 在一段指定时间内&#xff0c;监听用户感兴趣的文件描述符上的可读、可写和异常等事件是否就绪。 :::tips int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* except…

掌握 JavaScript:从初学者到高级开发者的完整指南之JavaScript对象(二)

JavaScript基础知识 1. JavaScript对象1.1.1 基本对象1.1.1.1 Array对象语法格式特点属性和方法 1.1.1.2 String对象语法格式属性和方法 1.1.1.3 JSON对象自定义对象json对象 1. JavaScript对象 可以大体分页3大类&#xff1a; 第一类&#xff1a;基本对象,我们主要学习Array…

Python---小海龟会画画---利用turtle(海龟)模块

1、小海龟模块 在Python3版本中&#xff0c;新增加了一个模块叫做turtle&#xff08;海龟&#xff09;&#xff0c;专门用于绘制图形图像 2、模块如何使用 ① 导入模块 import turtle② 使用turtle模块中已经定义好的方法 turtle.forward(数值) # 从左向右&#xff0c;绘制一…

docker 部署 若依 Ruoyi springboot+vue分离版 dockerCompose

本篇从已有虚拟机/服务器 安装好dokcer为基础开始讲解 1.部署mysql 创建conf data init三个文件夹 conf目录存放在mysql配置文件 init目录存放着若依数据库sql文件&#xff08;从navicat导出的并非若依框架自带sql&#xff09; 创建一个属于本次若依部署的网段&#xff08;只…

python:使用Scikit-image对遥感影像进行梯度特征提取(gradient)

作者:CSDN @ _养乐多_ 在本博客中,我们将介绍如何使用Scikit-Image来进行梯度特征提取(gradient),并且提供一个示例代码,演示了如何在单波段遥感图像上应用这些方法。 梯度特征是指用于表示图像中亮度或颜色变化的特征。它包括两个关键成分:梯度幅值和梯度方向。梯度幅…

吴恩达《机器学习》1-3:监督学习

一、监督学习 例如房屋价格的数据集。在监督学习中&#xff0c;我们将已知的房价作为"正确答案"&#xff0c;并将这些价格与房屋的特征数据一起提供给学习算法。学习算法使用这些已知答案的数据来学习模式和关系&#xff0c;以便在未知情况下预测其他房屋的价格。这就…

底层驱动day8作业

代码&#xff1a; //驱动程序 #include<linux/init.h> #include<linux/module.h> #include<linux/of.h> #include<linux/of_gpio.h> #include<linux/gpio.h> #include<linux/timer.h>struct device_node *dnode; //unsigned int gpiono; …

内存管理:TLSF算法

动态内存分配DSA DSA&#xff1a;Dynamic Storage Allocation&#xff0c;用于动态管理程序运行时所需的内存。动态内存分配涉及在程序运行时根据需要分配和释放内存&#xff0c;以存储数据结构和数据。 内存管理方式&#xff1a;动态内存分配与静态内存分配相对应&#xff0…

json格式存储b64编码的rgb raw数据

1.rgb raw数据准备 利用python将jpg里面的rgb raw数据提取出来。 import cv2# 读取 JPG 图像 image_path 1.jpg image cv2.imread(image_path)#imread读出来的顺序是BGR print("image shape:",image.shape)# 将图像由BGR转换为 RGB 数据 rgb_data cv2.cvtColor(im…

什么是水坑攻击

水坑攻击 1. 水坑攻击的概念1. 水坑攻击的原理2. 水坑攻击的常用手段3. 典型水坑攻击事件 1. 水坑攻击的概念 水坑攻击&#xff08;Watering Hole Attack&#xff09;是一种网络攻击方法&#xff0c;其名称来源于自然界的捕食方式。 攻击者会通过前期的调查或各种社会工程手段…

2023年【河北省安全员B证】免费试题及河北省安全员B证作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 河北省安全员B证免费试题考前必练&#xff01;安全生产模拟考试一点通每个月更新河北省安全员B证作业考试题库题目及答案&#xff01;多做几遍&#xff0c;其实通过河北省安全员B证在线考试很简单。 1、【多选题】一般…

计算机中了faust勒索病毒怎么办,faust勒索病毒解密,数据恢复

近年来网络技术得到了飞速发展&#xff0c;为人们的企业生产生活提供了极大便利&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期&#xff0c;云天数据恢复中心收到了很多企业的求助&#xff0c;企业的计算机服务器遭到了faust勒索病毒攻击&#xff0c;导致企业…