1.什么是SSM
SSM其实就是Spring Spring MVC MyBatis.Spring +Spring MVC+ MyBatis是一种常见的 Java 企业级开发框架组合,用于构建基于 MVC 设计模式 的 Web 应用程序。
各模块的作用:
Spring
- 核心功能:依赖注入(DI)、面向切面编程(AOP)、事务管理等。
- 用途:统一管理对象的生命周期和依赖关系,降低代码耦合度。
Spring MVC
- 核心功能:处理 HTTP 请求、响应、控制器(Controller)、视图解析等。
- 用途:实现 Web 层的逻辑控制,将用户请求转发到对应的业务逻辑。
MyBatis
- 核心功能:动态 SQL 映射、数据库持久化操作。
- 用途:简化 JDBC 操作,通过 XML 或注解定义 SQL 语句,避免手动拼接 SQL
接下来我们介绍下Spring MVC.
2.什么是Spring MVC
(a).MVC
MVC是一种软件设计架构模式.他把软件系统分为模型,视图,和控制器三个部分.
这种设计模式就是首先用户通过视图发送请求,此时控制器接收到请求之后会交给模型处理,处理完成后会返回结果给控制器,控制器再将结果返回给视图
View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型
来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型就像是我们去饭馆吃饭.服务员会将我们点的饭菜告诉柜台的收银人员,收银人员将菜单交给后厨,后厨只是负责做菜就可以,做完以后交给收银员,收银员交给服务员.最终我们到我们手里
上面的例子中
View(视图):就类似服务员,负责将我们的请求传递给收银员,并且最终给我们返回结果
Model(模型):就像是厨师,不关心外面的流程,只需要安心炒菜
Controller(控制器):就像是收银员,也就是服务员和后厨的中间人.有了中间人就可以就可以让他们进行交流.
(b).Spring MVC和MVC的关系
Spring MVC是基于MVC这种设计模式实现的.
(c).Spring Web MVC
Spring MVC的全称是Spring Web MVC.就是基于Spring MVC这种设计模式应用于网站开发.
Spring Web MVC 是 Spring 框架中用于实现 Web 层控制 的核心模块,属于 MVC 设计模式 的具体实现。它通过清晰的职责划分和高度灵活的配置,简化了 Web 应用的开发流程。
2.创建Spring项目
1.在idea上创建
首先创建项目-->定义好项目名称,选择语言,选择JDK版本-->接下来选择Spring Boot版本
已经想要引入的依赖即可.
2.在Spring官网创建(Spring Initializr)
3.在阿里云创建(Cloud Native App Initializer)
3.代码
首先我们写 一个简单的代码
package com.example.demo;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RequestMapping("/requst") @RestController public class HelloController {@RequestMapping("/hello")public String hello(){return "hello Spring";} }
输出:
4.学习使用Spring MVC
4.1流程
1.建立连接:代码和浏览器建立连接。
2.请求:用户使用浏览器发送请求,要在代码中获得这个请求。
3.响应:MVC这一套下来以后会有一个具体的响应,所以需要让这个响应返回给用户。
4.2建立连接
让浏览器和我们的后端代码建立连接需要用到@RequstMapping 和@RequstController.
这两个注解.
接下来我们先了解下这两个注解:
@RequstMapping
1.在Spring MVC中,控制器(Controller)类里的方法会用这个注解来指定处理的URL路径。
@RequestMapping("/hello")可能对应到某个处理请求的方法上。那这样的话,当用户访问/hello时,这个方法就会被调用.
2.这个注解还能指定HTTP方法,比如GET、POST等。也就是说,除了路径之外,还可以通过method属性来限制请求的类型。比如,@RequestMapping(value="/hello",
method=RequestMethod.GET)这样的话,只有GET请求才会被这个方法处理。
// 指定使用GET@RequestMapping(value = "/hello", method = RequestMethod.GET)public String sayHello() {return "hello, Spring MVC";}
3.这个注解可以应用在类级别和方法级别。如果类上有一个@RequestMapping("/api"),而方法上有@RequestMapping("/users"),那么完整的路径应该是/api/users。这样的话,可以避免在每个方法里重复写相同的路径前缀.
@RequstController
@RestController是Spring MVC中的一个注解,它结合了@Controller和@ResponseBody的功能。@RestController会将每个方法返回的对象自动转换为JSON或XML响应,省去了单独的@ResponseBody注解。同时,它还隐式地添加了@Controller的注解,因此不需要再手动添加就可以接收和处理 HTTP 请求。
5.传递参数
5.1传递单个参数
5.1.1String类型
@RequestMapping("/r1")public String r1(String name){return "name="+name;}
5.1.2int类型
@RequestMapping("/r2")public int r2(int age){return age;}
但是使用int会存在一个问题:
如果浏览器不传递参数,那么使用int就会报错,我们可以看到状态码为500,就是服务器内部错误.所以我们尽量使用引用类型.引用类型不传参数的话服务器会返回一个null
@RequestMapping("/r3")public String r3(Integer age){return "age="+age;}
5.1.3设置参数时,传递的参数要与方法中的参数一致.否则不会成功传值
5.1.4参数过多我们可以使用对象传入
package com.example.demo;public class Student {private String name;private Integer id;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", id=" + id +", age=" + age +'}';} }
@RequestMapping("/r4")public Student r4(Student student){return student;}
注:这里对象传入会有默认的初始化值,不传数据也会有,不会出现报错
5.1.5@RequestParam()
1.在传参中我们使用@RequestParam()注解,在URL中传参时只需要按照注解中的字符串传入即可.达到重命名效果
@RequestMapping("/r5")public String r5(@RequestParam("UserName") String name){return "name="+name;}
2.@RequestParam()还有一个机制:
使用@RequestParam()在URL或者body中必须要设置参数,否则就会报错
但是我们可以在注解中用关闭这个.默认是必填选项,不填的话会报400错误,也可以设置可以不填的选项,将required设置为false即可,这也是为了在后端开发的时候避免几个参数类似不好判断
3.@RequestParam()作用就是一个用于从 HTTP 请求的查询参数(URL 参数)或表单数据中提取值的注解。
下面这行代码就是将HTTP请求中的查询参数通过@RequestParam()注解提取出值保存在集合中
@RequestMapping("/r4")public String r4(@RequestParam List<String> list){return "接受数组="+list;}
5.1.6@RequstBody
如果在body(正文)中传入数据可能不会返回正确的响应.
将客户端发送的
HTTP 请求体(Request Body)
内容自动转换为 Java 对象,支持 JSON、XML 等数据格式@RequestMapping("/r4")public Student r4(Student student){return student;}
如果我们要在body(正文)中传输数据就需要使用@RequstBody注解
@RequestMapping("/r6")public Student r6(@RequestBody Student student){return student;}
此时我们再看下响应的结果
5.2传递数组
@RequestMapping("/r7")public String r7(String[] array){return "array="+Arrays.toString(array);}
5.3传递集合
@RequstParam注解在这里的作用就是将值提取出来放到集合中
@RequestMapping("/r8")public String r8(@RequestParam List<String> list){return "list="+list;}
5.4传递json
这里我们使用一个对象来接收 .
这里我们使用@RequstBody注解,可以将json格式的数据转换为Java 对象
@RequestMapping("/r5")public String r5( @RequestBody Student student){return "student="+student.toString();}
5.5json和字符串互转
这里我们使用ObjectMaper类来处理
package org.s.com.demo2;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper;public class jsonTest {private static ObjectMapper objectMapper=new ObjectMapper();public static void main(String[] args) throws JsonProcessingException {Student student=new Student();student.setId(5);student.setAge(20);student.setName("zhangsan");//字符串转jsonString s = objectMapper.writeValueAsString(student);System.out.println(s);//json转字符串Student student1=objectMapper.readValue(s,Student.class);System.out.println(student1.getAge()+student1.getName());} }
5.6获取URL中的参数
这里我们使用@PathVariable注解.
我们要注意格式,在URL中的路径要和@RequstMapping路径相同并且用{}将想要获取的参数括起来.@PathVariable中还要声明,要和@RequstMapping的一样
@RequestMapping("/r9/{num}")public String r9(@PathVariable("num") String num){return num;}
5.7上传文件
使用@RequstPart注解
@RequestMapping("/r10")public String r10(@RequestPart("file") MultipartFile file){return file.getOriginalFilename();}
5.8获取请求头中的信息
这里我们获取的是"User-Agent"
@RequestMapping("/r18")public String r18(HttpServletRequest request){String header = request.getHeader("User-Agent");return header;}
5.9获取一个html
这里我们要注意:如果使用@RestController注解默认是返回数据
所以我们要使用@Controller用来返回视图
同时我们还要注意返回视图的时候"/index.html"必须要加" / "否则也还是会报错
//输出一个html 页面必须要使用@Controller注解,因为@RestController是@RequstBody和@Controller的结合版//@RestController默认返回的是数据,@Controller默认返回视图//在返回视图时"/index.html"前面的斜杠不能省略,否则报错@RequestMapping("/r19")public String r19(){return "/index.html";}
5.10设置状态码
@RequestMapping("/r20")public String r20(HttpServletResponse response){response.setStatus(418);return "状态码设置成功";}
6.Cookie和Session
6.1Cookie
首先我们要了解什么是HTTP的"无状态"?
HTTP(HyperText Transfer Protocol)的无状态(Stateless)特性是指协议本身不会在两次请求之间自动保留用户或会话的状态信息。每个HTTP请求都是独立的,服务器默认不会记住之前的请求内容或用户身份。这种设计对性能和扩展性有重要影响,但也带来了一些挑战。
就类似于我们在某宝与客服聊天,聊天结束后如果再次和他聊天,虽然还是同一个客服,但是可能还是对你不熟悉.
但是在很多业务中我们都需要保存信息,比如某宝,在登录页面我们会设置 一次登录,如果没有
Cookie,在支付的时候还会让你再次登录,这样给用户带来的体验感就会很差.
⽐如去医院挂号1. 看病之前先挂号. 挂号时候需要提供⾝份证号, 同时得到了⼀张 "就诊卡", 这个就诊卡就相当于患 者的 "令牌".2. 后续去各个科室进⾏检查, 诊断, 开药等操作, 都不必再出⽰⾝份证了, 只要凭就诊卡即可识别出当前患者的⾝份.3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的⾝份和就诊卡的关联就销毁了. (类似于⽹站的注销操作)4. ⼜来看病, 可以办⼀张新的就诊卡, 此时就得到了⼀个新的 "令牌".此时服务器这边就需要记录"令牌信息",以及对应的 用户信息.这个就是Session机制所作的工作.6.2Session
简单来说Session就是会话的意思
在计算机领域, 会话是⼀个客⼾与服务器之间的不中断的请求响应. 对客⼾的每个请求,服务器能够识 别出请求来⾃于同⼀个客⼾. 当⼀个未知的客⼾向Web应⽤程序发送第⼀个请求时就开始了⼀个会话. 当客⼾明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了.服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个⽤⼾, 也就是属于 哪个会话, 就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系.Session就是服务器为了保存用户信息而创建的一个对象
Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构. Key 就是SessionID, Value 就是⽤⼾信息.
SessionId 是由服务器⽣成的⼀个 "唯⼀性字符串", 从 Session 机制的⻆度来看, 这个唯⼀性字符串称 为 "SessionId". 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 "token".上述例⼦中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息, ⽐如时间, 签名等.6.3工作流程
1. 当⽤⼾登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客⼾端. (通过 HTTP 响应中的 Set-Cookie 字段返回).2. 客⼾端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的 Cookie 字段带上).3. 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的⽤⼾信息, 再进⾏后 续操作.找不到则重新创建Session, 并把SessionID返回.
6.4Cookie和Session的区别
1.Cookie是客户端保存用户信息的一种机制,Session是服务器保存用户信息的一种机制
2.Cookie和Session之间主要是通过SessionID关联的
3.Cookie和Session经常会在一起配合使用.但是不是必须配合
6.5获取Cookie
1.传统方式:这里的HttpServletRequst是Spring内置的对象,通过这个对象我们就可以获取到请求头中的信息.请求头:HTTP请求头
@RequestMapping("/r11")public String r11(HttpServletRequest request){Cookie[] cookies = request.getCookies();StringBuilder stringBuilder=new StringBuilder();if(cookies!=null){for (Cookie ck:cookies){stringBuilder.append(ck.getName()+":"+ck.getValue());}}return "cookie="+stringBuilder;}
这里Cookie我们是可以自己设置的,所以Cooike不安全,容易造假
2.使用注解@RequestMapping("/r12")public String r12(@CookieValue("cook") String cook){return "cook="+cook;}
6.6Session的存储和获取
1.传统方式存储
@RequestMapping("/r13")public String r13(HttpServletRequest request){HttpSession session = request.getSession();if(session!=null){session.setAttribute("userName","zhangsan");}return "设置成功";}
2.传统方式获取
@RequestMapping("/r14")public String r14(HttpServletRequest request){HttpSession session = request.getSession();String name=null;if(session!=null&&session.getAttribute("userName")!=null){name = (String) session.getAttribute("userName");}return "sesson="+name;}
3.使用注解获取
@RequestMapping("/r15")public String r15(@SessionAttribute("userName")String name){return name;}
4.简洁获取
@RequestMapping("/r16")public String r16(HttpSession session){String name = (String)session.getAttribute("userName");return name;}