Spring Web MVC_spring-webmvc
目录
一.什么是 MVC?
二.什么是Spring MVC
三.使用Spring MVC
1.建立连接
@RequestMapping 路由映射
@RequestMapping注释定义详解:
@RestController
2.请求
a.传递单个参数,并且在@RequestMapping中限制请求方法是GET
b.传递多个参数
c.后端参数重命名
d.传递对象
e.传递数组
f.传递集合
h.传递Json数据
i.获取url中的参数
j.上传文件
k.Cookie和Session
获取Cookie:
获取Session:
获取Header:
3.响应
返回静态页面@Controller:
详解@RestController和@Controller:
返回数据@ResponsBody:
返回HTML代码段:
返回Json:
设置返回的状态码:
设置响应的Header:
一.什么是 MVC?
MVC 是一种软件架构模式,是一种思想
全称是 Model View Controller,它是软件工程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分:
M:Model(模型)
V: View(视图)
C: Controller(控制器)
它的核心思想是将应用程序分为三个部分,各司其职,从而让代码结构更清晰、职责更明确、便于维护和扩展。
二.什么是Spring MVC
MVC是一种软件架构设计思想,而Spring MVC是MVC这种设计思想的具体实现。
Spring Web MVC:Spring Web MVC 是 Spring Framework 的一个子模块,它是基于 MVC(Model-View-Controller)设计模式的 Web 应用开发框架。
Spring Web MVC 是构建在 Servlet API 上的原始 Web 框架,从一开始就包含在 Spring 框架中。正式名称“Spring Web MVC”来自其源模块的名称,但它通常被称为“Spring MVC”。
现在的后端人员并不设计前端页面的开发,所有View层现在基本上不返回页面了,现在View层返回的是数据。
三.使用Spring MVC
这个就是Spring MVC框架:
使用Spring MVC主要分为三步:建立连接,请求和响应
1.建立连接
@RequestMapping 路由映射
用将一个HTTP请求路径,映射到方法上,任何HTTP请求方式都可以接收,但是GET方法默认从查询参数中获取,POST方法默认从Body中获取。
当用户输入127.0.0.1:8080/HelloController/hello,就可以调用这个方法 。
注意:
@RequestMapping的URL路径最前面加不加/都可以,Spring程序启动时,会进行判断,如果前面没有/,Spring会自动拼接一个/:
@RequestMapping(\"user\")@RestControllerpublic class UserController { @RequestMapping(\"sayHi\") public String sayHi(){ return \"hello,Spring MVC\"; }}
使用/可以形成多级路径:
@RequestMapping(\"/user/m1\")@RestControllerpublic class UserController { @RequestMapping(\"/say/hi\") public String sayHi(){ return \"hello,Spring MVC\"; }}
@RequestMapping注释定义详解:
@RestController
既然@RequestMapping是用于路由映射的注解,那么@RestController是干什么的呢 ?
Spring会对所有的类进⾏扫描, 如果类加了注解@RestController, Spring才会去看这个类里面的方法有没有加 @RequestMapping 这个注解。
2.请求
Postman的安装及其使用https://blog.csdn.net/weixin_52159554/article/details/149093259?sharetype=blogdetail&sharerId=149093259&sharerefer=PC&sharesource=weixin_52159554&spm=1011.2480.3001.8118
a.传递单个参数,并且在@RequestMapping中限制请求方法是GET
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;//设置公共路由为ParamController,且限定该方法只能由GET请求方法调用@RequestMapping(value = \"/ParamController\", method = RequestMethod.GET)@RestControllerpublic class ParamController { @RequestMapping(\"/paramOne\") public String paramOne(String param){ return param; }}
在限制请求方法为GET的时候在使用POST方法请求时 :
当使用GET方法请求时:
在请求时,使用和路径映射方法的形参相同名称的查询参数,后端就可以接收到响应的值:
b.传递多个参数
//2.传递多个参数 @RequestMapping(\"/paramTwo\") public String paramTwo(String param1,String param2 ){ return \"接收到的参数是param1:\"+param1+\",param2:\"+param2; }
如果使用基本数据类型,如果在请求的时候没有传递对应的参数,在会报错:
如果使用包装类,如果没有传递对应的查询参数,则会自动赋值为null:
c.后端参数重命名
//3.后端参数重命名 @RequestMapping(\"/paramThree\") public String paramThree(@RequestParam(\"param1\") String str, Integer param2){ return \"接收到的参数是str:\"+str+\",param2:\"+param2; }
如果对参数进行了重命名,这个参数就变为必传参数了,此时如果不传这个参数是会报错的:
将@RequestParam 的required设置为false就可以了,此时这个参数就不是必传参数了:
d.传递对象
此时只需要创建一个用于接收参数类,并且用其接收查询参数,Spring会将接收到的查询参数,封装为方法中指定的对象。
对象中的成员变量可以不传递参数,会有默认的初始化的。
//4.传递一个对象 @RequestMapping(\"/paramFour\") public String paramFour(ParamInfo paramInfo){ return \"接收到的参数是:\" + paramInfo.toString(); }
定义一个用于接收查询参数的类:
public class ParamInfo { private String param1; private String param2; public String getParam1() { return param1; } public void setParam1(String param1) { this.param1 = param1; } public String getParam2() { return param2; } public void setParam2(String param2) { this.param2 = param2; } @Override public String toString() { return \"ParamInfo{\" + \"param1=\'\" + param1 + \'\\\'\' + \", param2=\'\" + param2 + \'\\\'\' + \'}\'; }}
e.传递数组
此时只需要在请求时将,传递的查询参数全部设置为指定的数组名就可以了:
//5.传递一个数组 @RequestMapping(\"/paramFive\") public String paramFive(String[] param1){ return \"接收到的参数是:\" + Arrays.toString(param1); }
还可以:
谷歌浏览器可以这样写,其他浏览器可能需要转义字符。
f.传递集合
//6.传递一个集合 @RequestMapping(\"/paramSix\") public String paramSix(@RequestParam List paramList){ return \"接收到的参数是:\" + paramList; }
加@RequestParam Spring会将接收到的查询参数,封装为一个集合:
h.传递Json数据
Json本质上就是一个表示对象的字符串,所以在后端通常使用对象来接收Json数据。
//7.传递Json @RequestMapping(\"/paramSeven\") public String paramSeven(@RequestBody ParamInfo paramInfo){ return \"接收到到参数是:\" + paramInfo.toString(); }
i.获取url中的参数
单个参数:
//8.获取url中的参数 @RequestMapping(\"/paramEight/{param}\") public String paramEight(@PathVariable Integer param){ return \"接收到的参数是:\" + param; }
多个参数:
//8.获取url中的参数 @RequestMapping(\"/paramEight/{param1}/{param2}\") public String paramEight(@PathVariable Integer param1,@PathVariable Integer param2){ return \"接收到的参数是:\" + param1; }
j.上传文件
@RequestMapping(\"/paramNine\") public boolean paramNine(@RequestPart MultipartFile file) throws IOException { file.transferTo(new File(\"E:/\" + file.getOriginalFilename())); return true; }
k.Cookie和Session
Cookie和Sessionhttps://blog.csdn.net/weixin_52159554/article/details/148929907?spm=1001.2014.3001.5502
获取Cookie:
使用Servlet获取:
@RequestMapping(\"/getCookieOne\") public String getCookieOne(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { System.out.println(cookie.getName() + \":\" + cookie.getValue()); } return \"获取Cookie成功!\"; }
HttpServletRequest 和 HttpServletResponse是Spring的内置对象:
注释的方式获取:
@RequestMapping(\"/getCookieTwo\") public String getCookieTwo(@CookieValue String aaa, @CookieValue String bbb, @CookieValue String ccc){ return \"aaa:\" + aaa + \" \" +\"bbb:\" + bbb + \" \" +\"ccc:\" + ccc; }
获取Session:
Servlet方式:
伪造Session:
在服务器中Session是可以保存在内存或者数据库中的:
@RequestMapping(\"/setSession\") public boolean setSession(HttpServletRequest request){ HttpSession session = request.getSession(); if(session != null){ session.setAttribute(\"userName\", \"张三\"); return true; } return false; }
获取Session:
@RequestMapping(\"/getSessionOne\") public String getSessionOne(HttpServletRequest request){ HttpSession session = request.getSession(false); if(session != null){ String userName = (String) session.getAttribute(\"userName\"); return \"获取到的Session是:\" + userName; } return null; }
注释的方式获取Session:
伪造Session:
@RequestMapping(\"/setSession\") public boolean setSession(HttpServletRequest request){ HttpSession session = request.getSession(); if(session != null){ session.setAttribute(\"userName\", \"张三\"); session.setAttribute(\"userAge\", 30); return true; } return false; }
获取Session:
@RequestMapping(\"/getSessionTwo\") public String getSessionTwo(@SessionAttribute String userName,@SessionAttribute String userAge){ return userName + \":\" + userAge; }
@RequestMapping(\"/getSessionThree\") public String getSessionThree(HttpSession session){ if(session != null){ String userName = (String) session.getAttribute(\"userName\"); Integer userAge = (Integer) session.getAttribute(\"userAge\"); return userName + \":\" + userAge; } return null; }
获取Header:
@RequestMapping(\"/getHeaderOne\") public String getHeader(HttpServletRequest request){ String userAgent = request.getHeader(\"user-agent\"); return \"userAgent\" + userAgent; } @RequestMapping(\"/getHeaderTwo\") public String getHeaderTwo(@RequestHeader(\"User-Agent\") String userAgent){ return \"userAgent\" + userAgent; }
3.响应
返回静态页面@Controller:
在Spring Boot项目中,网页一般保存在:
HTML代码如下:
Document Hello,Spring MVC,我是index页面。
当我们将HTML网页保存在这个路径后,在浏览器中输入相应的ip地址和端口号加上网页文件名,是可以访问到这个静态页面的:
此时的后端代码是:
@RequestMapping(\"/htmlController\")@RestControllerpublic class StaticHtmlController { @RequestMapping(\"/html\") public String getHtml(){ return \"/index.html\"; }}
此时的运行结果是:
我们最开始的期望是获取静态的HTML页面,结果却发现,页面未正确返回,http把“/index.html”当做了http响应正文的数据,那Spring MVC如何才能识别出来index.html 是一个静态页面呢?
此时需要将@RestController替换成@Controller:
详解@RestController和@Controller:
@Controller:
在最一开始,对于一个网站,几乎都是前后端结合开发的,所以后端也需要返回页面,但是随着发展,网站的功能和规模越来越大,在结合开发就会导致后期维护非常的繁琐,所以就将前后端分离开发了,所以现在后端只需要在原来返回视图的地方返回数据就可以了。
所以我们在前面使用的@RestController是用于返回数据的, 我们观察这个注释的定义可以发现:
除了上面的元注释,@RestController = @Controller + @ResponsBody。
@Controller: 定义一个控制器,Spring框架启动时加载,把这个对象交给Spring管理。
@ResponseBody:定义返回的数据格式为非视图,返回一个test/html信息。
所以当Controller层的类中的方法全都是返回数据的时候,直接在类上加@RestController就可以了,如果一个类中既有静态页面又有数据,就使用@Controller + @ResponsBody这两个注释配合使用。
@Controller只能用于修饰类。
使用了@Controller就不可以在使用@RestController了。
如果在既有数据返回又有页面返回的类中,只使用了@Controller,此时访问返回数据的方法时,就会报错,因为没有@ResponsBody注释,Spring就会认为这个方法返回的是页面,从而就会去找这个页面,但是是找不到的,所以就会报错。
返回数据@ResponsBody:
@ResponsBody既可以修饰方法又可以修饰类,修饰类的时候就表面这个类下面的方法都是返回数据的,修饰方法时只表示这个方法是返回数据的。
@RestponsBody不可以单独使用。
此时这种情况是因为,没有@Controller或RestController来告诉Spring容器,你需要来帮我托管这个类,所以Spring压根就不知道在方法中调用了@RequestMapping,所以就会导致找不到网页。
返回HTML代码段:
当后端返回String类型的数据时,会自动变为HTML代码。
后端在返回数据时,如果数据中包含HTML代码,也会被浏览器解析:
@RequestMapping(\"/HelloController\")@Controllerpublic class HelloController { @ResponseBody @RequestMapping(\"/hello\") public String sayHello() { return \"Hello,HTML~
\"; }}
返回Json:
当返回的数据是对象或者map的时候,会自动变为Json字符串:
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;@RequestMapping(\"/HelloController\")@Controllerpublic class HelloController { @ResponseBody @RequestMapping(\"/hello\") public HashMap sayHello() { HashMap map = new HashMap(); map.put(\"hello\", \"world\"); map.put(\"sayHello\", \"sayHello\"); map.put(\"sayGoodbye\", \"sayGoodbye\"); return map; }}
设置返回的状态码:
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;import java.util.HashMap;@RequestMapping(\"/HelloController\")@Controllerpublic class HelloController { @ResponseBody @RequestMapping(\"/hello\") public String sayHello(HttpServletResponse response) { response.setStatus(404); return \"设置状态码成功\"; }}
设置响应的Header:
@RequestMapping(\"/HelloController\")@Controllerpublic class HelloController { @ResponseBody @RequestMapping(value = \"/hello\") public String sayHello() { return \"{\'ok\':1}\"; }}
@RequestMapping(\"/HelloController\")@Controllerpublic class HelloController { @ResponseBody @RequestMapping(value = \"/hello\",produces = \"application/json;charset=utf-8\") public String sayHello() { return \"{\'ok\':1}\"; }}