Spring Web MVC入门

一:了解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,方法名是sayHipublic 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;}@Overridepublic 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;}@Overridepublic 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则放回nullHttpSession 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.rhkb.cn/news/173997.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

缓解大模型幻觉问题的解决方案

本文记录大模型幻觉问题的相关内容。 参考&#xff1a;Mitigating LLM Hallucinations: a multifaceted approach 地址&#xff1a;https://amatriain.net/blog/hallucinations &#xff08;图&#xff1a;解决大模型幻觉的不同方式&#xff09; 什么是幻觉&#xff1f; 幻觉…

常见面试题-MySQL专栏(一)

为什么 mysql 删了行记录&#xff0c;反而磁盘空间没有减少&#xff1f; 答&#xff1a; 在 mysql 中&#xff0c;当使用 delete 删除数据时&#xff0c;mysql 会将删除的数据标记为已删除&#xff0c;但是并不去磁盘上真正进行删除&#xff0c;而是在需要使用这片存储空间时&…

Linux之线程池

线程池 线程池概念线程池的应用场景线程池实现原理单例模式下线程池实现STL、智能指针和线程安全其他常见的各种锁 线程池概念 线程池&#xff1a;一种线程使用模式。 线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待…

如何在Node.js中使用环境变量或命令行参数来设置HTTP爬虫ip?

首先&#xff0c;定义问题&#xff1a;在 Node.js 应用程序中&#xff0c;我们可以通过环境变量或命令行参数来设置HTTP爬虫ip&#xff0c;以便在发送请求时使用这些HTTP爬虫ip。 亲身经验&#xff1a;我曾经需要为一个项目设置HTTP爬虫ip&#xff0c;以便在发送请求时使用这些…

EtherNet Ip工业RFID读写器与欧姆龙PLC 配置示例说明

一、准备阶段 POE交换机欧姆龙PLC 支持EtherNet Ip协议CX-Programmer 9.5配置软件 二、配置读卡器 1、打开软件 2、选择网卡&#xff0c;如果多网卡的电脑请注意对应所接的网卡&#xff0c;网卡名一般为“Network adapter Realtek PCIe GBE Family” 3、点击“选择网卡”&…

Node学习笔记之user用户API模块

1、获取用户的基本信息 步骤 获取登录会话存储的session中用户的id判断是否获取到id根据用户id查询数据库中的个人信息检查指定 id 的用户是否存在将密码设置为空将数据返回给前端 // 获取用户信息数据 exports.userinfo (req, res) > {(async function () {// 1. 获取…

BUUCTF rar 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 这个是一个rar文件&#xff0c;里面好像隐藏着什么秘密&#xff0c;但是压缩包被加密了&#xff0c;毫无保留的告诉你&#xff0c;rar的密码是4位纯数字。 密文&#xff1a; 下载附件&#xff0c;解压得到一个rar压…

MySQL---JDBC编程

文章目录 什么是JDBC&#xff1f;JDBC的工作原理JDBC的使用添加驱动创建数据源DataSource创建数据库连接Connection创建操作命令Statement执行SQL指令释放资源 通过JDBC演示CRUD新增查询&#xff08;需要增加一步 遍历结果集合的操作&#xff09;修改删除 什么是JDBC&#xff1…

Qt界面实现中英文切换

要实现的效果&#xff0c;是下拉列表切换中文和English实现按钮文本中英文内容切换。 实现步骤&#xff1a; 1.在VS中鼠标对Translation Files文件右击&#xff0c;选择“添加”--->“模块”. 在弹窗的窗口中选择“Qt”--->“Qt Translation File”。 添加Translation_e…

BIOS MBR UEFI GPT详解

先来看下名词 启动方式&#xff1a; BIOS&#xff1a;Basic Input Output System&#xff0c;中文名称"基本输入输出系统"。 UEFI&#xff1a;Unified Extensible Firmware Interface&#xff0c;中文名称"统一的可扩展固件接口"。 Legacy&#xff1a;…

DAY38 动态规划 + 509. 斐波那契数 + 70. 爬楼梯 + 746. 使用最小花费爬楼梯

动态规划理论 动态规划&#xff0c;Dynamic Programming&#xff0c; DP&#xff0c; 如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#xff0c;贪心没有状态推导…

【Git】HEAD detached from xxx 问题及解决方案

问题背景 最近用git的时候遇到了一个问题&#xff0c;场景是这样的。 我有一个分支main&#xff0c;其中有两个commit A和B&#xff0c;A是最新commit&#xff0c;B是历史commit。我先切到B看了看之前的代码&#xff0c;然后切到A&#xff0c;并进行了一些代码修改&#xff0…

AD教程(一)工程组成及创建

AD教程&#xff08;一&#xff09;工程组成及创建 工程组成 原理图库 绘制电阻模型、芯片模型、电容模型等&#xff0c;即将元件模型绘制出来。 原理图 将绘制的原件模型放置到原理图中&#xff0c;然后再添加连接的导线、网络标号。器件和器件之间的连接关系&#xff0c;在原…

SDL事件处理以及线程使用(2)

事件使用 #include <stdio.h> #include <SDL.h>#define FF_QUIT_EVENT (SDL_USEREVENT 1) // 定义自定义事件#undef main int main() {SDL_Window* pWindow NULL;SDL_Init(SDL_INIT_VIDEO);// 创建窗口pWindow SDL_CreateWindow("Event Test Title&…

【方法】如何给PDF文件添加“打开密码”?

PDF文件可以在线浏览&#xff0c;但如果想要给文件添加“打开密码”&#xff0c;就需要用到软件工具&#xff0c;下面小编分享两种常用的工具&#xff0c;小伙伴们可以根据需要选择。 工具一&#xff1a;PDF编辑器 PDF阅读器一般是没有设置密码的功能模块&#xff0c;PDF编辑器…

深入浅出排序算法之希尔排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每一组内的记录进行排序。然后&#xf…

7.scala方法初探

概述 在 scala 中&#xff0c;方法定义在内中&#xff0c;这点类似于 java &#xff0c;此文说明如何定义方法&#xff0c;及方法一些 用法 相关链接 阅读之前&#xff0c;可以先行浏览一下 官方文档 scala相关文章 定义一个参数的方法 这个例子定义了一个名为 double 方法&a…

【Linux】权限完结

个人主页点击直达&#xff1a;小白不是程序媛 系列专栏&#xff1a;Linux被操作记 目录 前言 chown指令 chgrp指令 文件类型 file指令 目录的权限 粘滞位 umask指令 权限总结 前言 上篇文章我们说到对于一个文件所属者和所属组都是同一个人时&#xff0c;使用所属者身…

Linux(Centos7)操作记录

1、nginx -t #Nginx配置文件检查 上述截图代表检查没问题 上述截图检查配置文件配置错误&#xff0c;并提示错误文件位置 2、systemctl restart nginx #重启Nginx 重启Nginx失败 3、systemctl status nginx.service #查看Nginx服务状态 80端口被占导致服务启动失败 4、n…

DVWA-SQL Injection SQL注入

概念 SQL注入&#xff0c;是指将特殊构造的恶意SQL语句插入Web表单的输入或页面请求的查询字符串中&#xff0c;从而欺骗后端Web服务器以执行该恶意SQL语句。 成功的 SQL 注入漏洞可以从数据库中读取敏感数据、修改数据库数据&#xff08;插入/更新/删除&#xff09;、对数据…