文章目录
- 【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
- SpringMVC概述
- 1. 三层架构与MVC架构区别
- 1.1 三层架构
- 1.2 MVC架构
- 1.3前后端分离开发模式
- 2. SpringMVC环境搭建
- 2.1 注解启动方式
- 2.2 xml启动方式
- 2.3 SpringMVC PostMan工具使用
- 3. SpringMVC 请求与响应
- 3.1 springmvc 5种接受参数类型
- 3.2 springmvc接受json数据
- 3.3 springmvc响应json数据
- 3.4使用HttpServletRequest 获取参数
- 3.5 springmvc restful简单介绍
- 3.6 springmvc 整合jsp技术(过时 了解该技术)
- 4. spring+springmvc+mybatis整合
- 4.1SSM环境的整合之提供增删改查
- 4.2 SSM环境的整合之配置整合
- 4.3 接口响应状态码
- 4.4 整合全局捕获异常
【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
SpringMVC概述
- SpringMVC 是一种基于 Java 实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,它和 Struts2 都属于表现层的框架,属于 Spring FrameWork 的后续产品,Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。
- SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成 为最优秀的 MVC 框架,它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。
简单总结:SpringMVC是一种基于Java实现MVC模型轻量级框架, 底层基于Servlet封装
1. 三层架构与MVC架构区别
1.1 三层架构
表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。 servlet层
业务逻辑层:对我们数据实现业务逻辑的封装 service层
数据访问层:对数据库访问操作 dao层
com.zhaoli.servlet
----表示层
com.zhaoli.service
----业务逻辑层
com.zhaoli.dao
----数据库访问层
1.2 MVC架构
M 代表 模型(Model)
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
- M 代表 模型(Model)(业务逻辑层+数据库访问组合)
模型就是数据,就是 dao,bean
模型是应用程序中用于处理应用程序数据逻辑的部分。
通常模型对象负责在数据库中存取数据。 - V 代表 视图(View)(前端)
视图就是网页, JSP,用来展示模型中的数据
视图是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。 - C 代表 控制器(controller)
控制器的作用就是把不同的数据(Model),显示在不同的视图(View)上,Servlet 扮演的就是这样的角色。
控制器是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
- 三层是基于业务逻辑来分的,而MVC是基于页面来分的
- 三层是软件架构,通过接口实现编程;MVC模式是一种复合设计模式,一种解决方案
- 三层模式是体系结构模式,MVC是设计模式
- 三层模式又可归于部署模式,MVC可归于表示模式
1.3前后端分离开发模式
体现 让专业的人做专业的事情,前端代码由前端来完成,后端代码由我们后端来完成,后端程序只需要将接口数据提供给前端调用即可。
前端:vue、饿了么UI、网页数据 例如 html、js、css
后端:接口中数据 springmvc+mybatis
将前端和后端代码分开的
View视图层—jsp、ftl、js、css
com.zhaoli.controller
----控制层springmvc 底层基于servlet封装 控制页面跳转、控制页面展示数据
com.zhaoli.controller
----返回json 给前端
com.zhaoli.service
----业务逻辑层
com.zhaoli.dao
----数据库访问层
2. SpringMVC环境搭建
2.1 注解启动方式
创建maven工程
Maven依赖
<!-- 整合springmvc框架依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
创建控制器层
package com.zhaoli.controller;
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;
@Controller
public class MayiktController {
/**
* 1.@Controller 标记该类是为 SpringMVC控制类
* 2.@RequestMapping("") 定义url映射 类似与servlet里面的@WebServlet("")
* 3.@ResponseBody 该接口返回我们的json数据
*/
/**
* 访问到请求 返回json数据
*/
public String getMayikt() {
//访问该接口的 返回json数据
return "{code:'200',mgs:'ok'}";
}
}
创建配置类
package com.zhaoli.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.zhaoli.controller")
public class SpringMVCConfig {
/**
* 1.@Configuration 相当于定义了SpringMVCConfig.xml配置文件
* 2.@ComponentScan("com.zhaoli.controller") 将该包下所有的类注入到IOC容器中
* 3.在SpringMVC原理中所有请求过来先到达我们的DispatcherServlet分发到具体控制类的方法进行执行
*/
}
注册配置类
package com.zhaoli.config;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
public class ServletInitializer extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
//注册我们的 SpringMVC config 配置类
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext =
new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.register(SpringMVCConfig.class);
return annotationConfigWebApplicationContext;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};//拦截所有的servlet请求
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
maven tomcat插件运行
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>85</port>
<path>/</path>
<ignorePackaging>true</ignorePackaging>
</configuration>
</plugin>
</plugins>
</build>
之后运行要是没有反应 先点击
之后再运行项目
在添加 servlet 依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
看到这样就是运行成功了
搭建环境常见问题
1.扫包范围填写错误 @ComponentScan(“com.mayikt.controller”) 导致接口访问404
2.在控制类没有加上@Controller 导致接口访问404
2.2 xml启动方式
Maven依赖
<!-- 整合springmvc框架依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
创建控制器层
package com.zhaoli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MayiktController {
@RequestMapping("getMayikt")
public String getMayikt(){
return "ok";
}
}
spring-mvc.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 此 spring-mvc.xml 就相当于新建了一个类(SpringMVCConfig) 并且在该类上加上了 @Configuration -->
<!--配置spring创建容器时要扫描的包 相当于在类(SpringMVCConfig)加上了@ComponentScan("com.zhaoli.controller") -->
<context:component-scan base-package="com.zhaoli.controller"></context:component-scan>
<!-- 配置spring开始注解mvc的支持 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
这是配置 spring-mvc.xml 的模板可以直接粘贴
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
注意粘贴时将这一段代码替换掉
web.xml配置
所有请求过来都是先达到我们的DispatcherServlet
springmvc 基于 Servlet封装
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!-- 此 web.xml 就相当于新建了一个类(ServletInitializer extends AbstractDispatcherServletInitializer) -->
<!-- 配置 springmvc -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<!-- java反射机制加载 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- servlet初始化加载我们的 spring-mvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 让我们的 springmvc DispatcherServlet优先加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 客户端所有请求都会到达我们的 DispatcherServlet (包括静态资源 控制器类中的请求) -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<display-name>Archetype Created Web Application</display-name>
</web-app>
这是配置 web.xml 的模板可以直接粘贴
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
注意粘贴时将这一段代码替换掉
外部tomcat运行
需要将这些jar包存入 tomcat的lib目录 否则将会报错找不到类该类
2.3 SpringMVC PostMan工具使用
PostMan简介
一 简介 Postman 是一款功能超级强大的用于发送 HTTP 请求的 Chrome插件 。做web页面开发和测试的人员会使用到该工具其主要特点 特点: 创建 + 测试:创建和发送任何的HTTP请求,使用PostMan发送 Get、Post、Delete请求等。
3. SpringMVC 请求与响应
@RequestMapping
@RequestMapping
注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。
如果加载方法上就是具体访问路径 如果加载类上就是我们访问的前缀
springmvc 定义url路径是不允许重复
package com.zhaoli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class UserController {
/**
* /add UserController.add OrderController.add?
* 如果我们将@RequestMapping注解加在我们的类上面 是访问该接口前缀
* 如果加在方法上就是我们具体的访问路径
* /user/add
*/
@RequestMapping("/add")
@ResponseBody
public String add() {
return "add ok";
}
@RequestMapping("/delete")
@ResponseBody
public String delete() {
return "delete ok";
}
@RequestMapping("/select")
@ResponseBody
public String select() {
return "delete ok";
}
}
package com.zhaoli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/order")
public class OrderController {
@RequestMapping("/add")
@ResponseBody
public String add() {
return "add ok";
}
@RequestMapping("/delete")
@ResponseBody
public String delete() {
return "delete ok";
}
}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method com.mayikt.controller.UserController#add() to { /add}: There is already 'orderController' bean method com.mayikt.controller.OrderController#add() mapped.
报错原因是因为 /add 这个url 路径在UserController类和 orderController类中都有
接受Get/Post请求参数
和Controller层方法的形参同名,那么可以直接通过参数名接收值即可
package com.zhaoli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MemberController {
/**
* addMember
* RequestMapping 默认的情况下 RequestMapping支持所有请求方式 例如 get、post 、delete
* method = RequestMethod.POST 设定该接口支持的POST
*/
@RequestMapping(value = "/addMember", method = RequestMethod.POST)
@ResponseBody
public String addMemberPost(Integer id, String name) {
System.out.println("id:" + id);
System.out.println("name:" + name);
return "ok";
}
/**
* addMember
* RequestMapping 默认的情况下 RequestMapping支持所有请求方式 例如 get、post 、delete
* method = RequestMethod.GET设定该接口支持的类型 GET
*
*/
@RequestMapping(value = "/addMember", method = RequestMethod.GET)
@ResponseBody
public String addMemberGet(Integer id, String name) {
System.out.println("id:" + id);
System.out.println("name:" + name);
return "ok---get";
}
}
3.1 springmvc 5种接受参数类型
普通参数、对象参数、嵌套对象参数、数组参数、集合普通参数
1. 普通参数
- url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数;
- 如果发生url地址传参,地址参数名与形参变量名不同,使用@RequestParam绑定参数关系;
参数:
required
:是否为必传参数
defaultValue
:参数默认值
package com.zhaoli.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MayiktDemoController {
//springmvc5种接受参数类型
/**
* 1.普通参数
*/
@RequestMapping("/demo01")
@ResponseBody
public String demo01(String name, Integer age) {
return "name:" + name + ",age:" + age;
}
/**
* @RequestParam(name="name",required = false)
* name="name" 传递的参数名称为 name 方法形参名称 mayiktName
* required = false 是否必须传递该参数 默认为 true (必须传递改参数) 若为 false 可不传递该参数
*/
@RequestMapping("/demo02")
@ResponseBody
public String demo02(@RequestParam(name = "name", required = false) String mayiktName, @RequestParam(name = "age", required = false) Integer mayiktAge) {
return "mayiktName:" + mayiktName + ",mayiktAge:" + mayiktAge;
}
}
报错原因:未传递 name 值
2.对象参数
请求参数名与形参对象属性名相同,定义对象类型形参即可接收参数
package com.zhaoli.entity;
public class UserEntity {
String userName;
Integer age;
}
/**
* 2.对象参数
*/
@RequestMapping("/demo03")
@ResponseBody
public String demo03(UserEntity user) {
return "userNmae:" + user.getUserName() + ",age:" + user.getAge();
}
3.嵌套对象参数
嵌套对象参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套对象属性参数
package com.zhaoli.entity;
public class UserInfo {
String addres;//地址
}
package com.zhaoli.entity;
public class UserEntity {
String userName;
Integer age;
UserInfo userInfo;
}
/**
* 3.嵌套对象参数
* 地址栏传递 addres 值时必须用: userInfo.addres
*/
@RequestMapping("/demo04")
@ResponseBody
public String demo04(UserEntity user) {
return "userNmae:" + user.getUserName() + ",age:" + user.getAge()+",addres:"+user.getUserInfo().getAddres();
}
报错原因:没有传递嵌套对象的值
4.数组参数
请求参数名与形参属性名相同且请求参数为多个,定义数组类型形参即可接收参数
/**
* 4.数组参数
* demo05?arrays=zhaoli&arrays=fanjing
*/
@RequestMapping("/demo05")
@ResponseBody
public String demo05(String[] arrays) {
return Arrays.toString(arrays);
}
5.集合保存普通参数
请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam
绑定参数关系
@RequestParam
:同名请求参数可以使用@RequestParam
注解映射到对应名称的集合对象中作为数据
/**
* 5.集合保存普通参数
* list 集合类型
*/
@RequestMapping("/demo06")
@ResponseBody
public String demo06(@RequestParam List<String> arrays) {
return Arrays.toString(arrays.toArray());
}
报错原因:没在List<String> arrays
前面加上 @RequestParam
3.2 springmvc接受json数据
开启接受json数据
package com.zhaoli.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan("com.zhaoli.controller")
@EnableWebMvc
public class SpringMVCConfig {
/**
* 1.@Configuration 相当于定义了SpringMVCConfig.xml配置文件
* 2.@ComponentScan("com.zhaoli.controller") 将该包下所有的类注入到IOC容器中
* 3.在SpringMVC原理中所有请求过来先到达我们的DispatcherServlet分发到具体控制类的方法进行执行
*/
}
maven依赖
<!-- @RequestBody 接收 json 数据 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
接受参数加上@RequestBody
UserEntity
userEntity
标记 接受json
数据
自动根据json数据反序列化成对象userEntity
1.以实体类方式接收
实体类
public class UserEntity {
String userName;
Integer age;
UserInfo userInfo;
}
public class UserInfo {
String addres;//地址
}
package com.zhaoli.controller;
import com.zhaoli.entity.UserEntity;
import org.springframework.stereotype.Controller;
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.ResponseBody;
import java.util.Arrays;
import java.util.List;
@Controller
public class MayiktDemoController {
/**
* 接受 json 数据
* 1.以实体类方式
*/
@RequestMapping("/demo07")
@ResponseBody
public String demo07(@RequestBody UserEntity userEntity){
return userEntity.toString();
}
}
2.以Map接收
json
数据 key
是为 Map
的key
value
Map
的value
需要注意json
数据value
与Map
集合value
类型保持一致否则报错
/**
* 接受 json 数据
* 2.以Map接收
*/
@RequestMapping("/demo08")
@ResponseBody
public String demo08(@RequestBody Map<String,String> paramMap){
return paramMap.toString();
}
@RequestMapping("/demo09")
@ResponseBody
public String demo09(@RequestBody Map<String,Object> paramMap){
return paramMap.toString();
}
3.以List接收
/**
* 接受 json 数据
* 3.以List接收
*/
@RequestMapping("/demo10")
@ResponseBody
public String demo10(@RequestBody List<String> lists) {
return lists.toArray().toString();
}
@RequestMapping("/demo11")
@ResponseBody
public String demo11(@RequestBody List<UserEntity> lists) {
return lists.toArray().toString();
}
3.3 springmvc响应json数据
- 在接口上加上
@ResponseBody
根据该方法返回值 返回对应json数据 底层 根据返回值 序列化成json
数据。 @RestController
标记该控制类所有接口都是返回json数据
package com.zhaoli.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* @RestController 标记该控制类所有接口都是返回 json 数据
* 相当于这两个同时作用 @Controller @ResponseBody
*/
@RestController
public class MayiktRestController {
@RequestMapping("/getRestMayikt")
public Map<String, Object> getMayikt() {
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("code", "200");
result.put("msg", "ok");
//访问该接口的 返回json数据
return result;
}
}
3.4使用HttpServletRequest 获取参数
springmvc
底层基于Servlet
Servlet HttpServletRequest HttpServletResponse
获取httprequest/response
三种方式
public String mayikt(HttpServletRequest request,HttpServletResponse response)
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
@Autowired
private HttpServletRequest request;
3.5 springmvc restful简单介绍
什么是restful
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格规范。基于这个风格设计的软件可以更简洁,更有层次。
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
传统方式操作资源:通过不同的参数来实现不同的效果,post 和 get。
http://127.0.0.1/mayikt/getUser?id=1
查询,GET 用户id是为1信息
http://127.0.0.1/mayikt/saveUser
新增,POST
http://127.0.0.1/mayikt/updateUser
更新,POST
http://127.0.0.1/mayikt/deleteUser?id=1
删除,GET
(查询、删除)get 写操作(新增、修改)Post
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果
例如:请求地址一样,但是实现的效果不一样 例如
发送请求get 执行查询、 发送POST 执行新增、发送PUT执行更新、发送DELETE执行删除
http://127.0.0.1/user/1
查询,GET
http://127.0.0.1/user
新增数据,POST
http://127.0.0.1/user
更新,PUT
http://127.0.0.1/user/1
删除,DELETE
根据发送不同的类型 判断 访问不同的接口
restful案例演示
在@RequestMapping
的value
中使用URI template
({变量名}),然后在@RequestMapping
注解方法的需要绑定的参数前,使用@PathVariable
指定变量名(如果变量名和参数名一致也可以不指定),从而将URL
中的值绑定到参数上。
@RequestMapping
组合注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
package com.zhaoli.controller;
import com.zhaoli.entity.UserEntity;
import org.springframework.web.bind.annotation.*;
@RestController
public class MayiktUserRestfulController {
/**
* Restful api 请求地址都是一样 根据不同请求方法判断
* USer 增加/删除/修改/查询 api接口
*/
/**
* 提供根据 id 查询接口 ---请求方法的类型 GET 指定请求类型为 GET
* /user/{id} :比如传递 user/1 就是将 1赋值给 id
*/
// @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
@GetMapping(value = "/user/{id}")
public UserEntity getUser(@PathVariable("id") Integer id) {
System.out.println("[getUser] id:" + id);
return new UserEntity("mayikt" + id, 22);
}
/**
* 提供根据 id 删除接口 ---请求方法的类型 DELETE 指定请求类型为 DELETE
*/
// @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
@DeleteMapping(value = "/user/{id}")
public String deleteUser(@PathVariable("id") Integer id) {
System.out.println("[deleteUser] id:" + id);
return "delete ok" + id;
}
/**
* 新增添加数据接口 ---请求方法的类型 POST 指定请求类型为 POST
* 传递 json 数据
*/
// @RequestMapping(value = "/user", method = RequestMethod.POST)
@PostMapping(value = "/user")
public String addUser(@RequestBody UserEntity userEntity) {
System.out.println("[addUser] userEntity:" + userEntity);
return "add ok";
}
/**
* 修改数据接口 ---请求方法的类型 PUT 指定请求类型为 PUT
* 传递 json 数据
*/
// @RequestMapping(value = "/user", method = RequestMethod.PUT)
@PutMapping(value = "/user")
public String updateUser(@RequestBody UserEntity userEntity) {
System.out.println("[updateUser] userEntity:" + userEntity);
return "update ok";
}
}
3.6 springmvc 整合jsp技术(过时 了解该技术)
核心配置
package com.mayikt.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan("com.mayikt.controller")
@EnableWebMvc
public class SpringMVCConfig implements WebMvcConfigurer {
/**
* 1.@Configuration 定义SpringMVCConfig.xml配置文件
* 2.需要将我们的控制类注入到ioc容器 @ComponentScan("com.mayikt.controller")
* @ComponentScan("com.mayikt.controller")将该包下所有的类 注入到IOC容器种
* 3.在springmvc原理 所有请求过来先达到我们的 DispatcherServlet 分发具体控制类 方法执行
*
*
* @Configuration
* SpringMVCConfig.java @Configuration
* springmvc.xml=== SpringMVCConfig.java
* -->
*/
//WebMvcConfigurer
@Bean
public InternalResourceViewResolver resourceViewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
//请求视图文件的前缀地址
internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
//请求视图文件的后缀
internalResourceViewResolver.setSuffix(".jsp");
internalResourceViewResolver.setExposeContextBeansAsAttributes(true);
return internalResourceViewResolver;
}
/**
* 视图配置
*
* @param registry
*/
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(resourceViewResolver());
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
webapp 目录下创建 WEB-INF/jsp 存放jsp
定义控制器
package com.mayikt.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
@Controller
public class MayiktJspController {
@RequestMapping("/mayiktJsp")
public String mayiktJsp() {
return "mayikt";
}
}
定义jsp页面
<%--
Created by IntelliJ IDEA.
User: mayikt
Date: 2022/7/29
Time: 16:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>mayikt</title>
</head>
<body>
springmvc整合jsp
</body>
</html>
4. spring+springmvc+mybatis整合
项目技术需求分析
使用ssm+layui技术开发 对用户表数据实现增删改查
采用前后端分离架构模式
4.1SSM环境的整合之提供增删改查
整合数据库表结构
CREATE TABLE `mayikt_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR ( 255 ) CHARACTER
SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`age` INT DEFAULT NULL,
`addres` VARCHAR ( 255 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB AUTO_INCREMENT = 48 DEFAULT CHARSET = utf8mb3;
整合maven依赖
<dependencies>
<!--整合springmvc 底层会自动整合spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--整合mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mysql 驱动架包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<!--使用alibaba数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!-- servlet 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--使用@ResponseBody 能够响应数据 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
实体类层
package com.zhaoli.entity;
public class UserEntity {
private Integer id;
private String name;
private Integer age;
private String addres;//地址
}
数据库访问层
package com.zhaoli.mapper;
import com.zhaoli.entity.UserEntity;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface UserMapper {
/**
* mybatis 注解方式
*/
@Insert("INSERT INTO mayikt_users VALUES(null,#{name},#{age},#{addres});")
int insertUser(UserEntity userEntity);
@Delete("DELETE mayikt_users WHERE id=#{id};")
int deleteById(Integer id);
@Update("UPDATE mayikt_users SET name=#{name},aeg=#{age},addres=#{addres} WHERE id=#{id};")
int update(UserEntity userEntity);
@Select("SELECT * FROM mayikt_users WHERE id=#{id};")
UserEntity getById(Integer id);
}
业务逻辑层
package com.zhaoli.service;
import com.zhaoli.entity.UserEntity;
import com.zhaoli.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service //将该类注入到 ioc 容器中
public class UserService {
@Autowired
private UserMapper userMapper;
public int insertUser(UserEntity userEntity) {
return userMapper.insertUser(userEntity);
}
public int deleteById(Integer id) {
return userMapper.deleteById(id);
}
public int update(UserEntity userEntity) {
return userMapper.update(userEntity);
}
public UserEntity getById(Integer id) {
return userMapper.getById(id);
}
}
控制层
package com.zhaoli.controller;
import com.zhaoli.entity.UserEntity;
import com.zhaoli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 标记该类是为 SpringMVC控制类
* 在该类中定义的接口都是返回 json 数据
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 根据id查询数据
*/
@GetMapping("/getById/{id}")
public UserEntity getById(@PathVariable("id") Integer id) {
return userService.getById(id);
}
/**
* 修改数据
*/
@PutMapping("/update")
public int update(@RequestBody UserEntity userEntity) {
return userService.update(userEntity);
}
/**
* 根据 id 删除数据
*/
@DeleteMapping("/deleteById/{id}")
public int deleteById(@PathVariable("id") Integer id) {
return userService.deleteById(id);
}
/**
* 新增数据
*/
@PostMapping("/insertUser")
public int insertUser(@RequestBody UserEntity userEntity) {
return userService.insertUser(userEntity);
}
}
4.2 SSM环境的整合之配置整合
JdbcConfig
package com.zhaoli.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
public class JdbcConfig {
/**
* 配置数据源信息
* 注入到 ioc 容器中
*
* @Bean 相当于在xml中的 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource.DruidDataSource"></bean>
*/
@Bean
public DataSource dataSource() {
//配置阿里巴巴数据源连接池
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/mayikt_springmvc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT");
druidDataSource.setUsername("root");
druidDataSource.setPassword("20020806");
return druidDataSource;
}
/**
* 数据源事务相关的配置
*
* @Autowired DataSource dataSource 自动在 ioc 容器中去找
*/
// @Bean
public PlatformTransactionManager platformTransactionManager(@Autowired DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
//设置数据源
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
MybatisConfig
package com.zhaoli.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(@Autowired DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//实体类层包
sqlSessionFactoryBean.setTypeAliasesPackage("com.com.zhaoli.entity");
return sqlSessionFactoryBean;
}
}
SpringConfig
package com.zhaoli.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//相当于创建了一个 SpringConfig.xml 即标记此类为配置类
@Configuration
//mybatis 扫包范围
@MapperScan("com.zhaoli.mapper")
//业务逻辑层的扫包范围
@ComponentScan("com.zhaoli.service")
//开启事务
@EnableTransactionManagement
//导入相关配置 相当于将这些类的配置拷贝进 SpringConfig.xml
@Import({JdbcConfig.class, MybatisConfig.class})
public class SpringConfig {
}
SpringMVCConfig
package com.zhaoli.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
//开启 springmvc
@EnableWebMvc
//相当于创建了一个 SpringMVCConfig.xml 即标记此类为配置类
@Configuration
//控制层的扫包范围
@ComponentScan("com.zhaoli.controller")
public class SpringMVCConfig {
}
ServletConfig
package com.zhaoli.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 加载 spring 相关配置
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ServletConfig.class};
}
/**
* 加载 springMVC 相关配置
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfig.class};
}
/**
* 拦截所有的请求
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
4.3 接口响应状态码
统一规范返回数据的格式,此处以json格式为例。返回数据应包含:返回状态码、返回状态信息、具体数据。
格式规范如下:
{
"code":"200",
"msg":"ok",
"data": {
//json格式的具体数据
}
}
查询到数据
{
"code":"200",
"msg":"ok",
"data": {
"userName":"mayikt",
"age":22
}
}
前端 ajax技术
if(code==200){
"data": {
"userName":"mayikt",
"age":22
}
}
Api Code状态码
1**
服务器收到请求,需要请求者继续执行操作
2**
操作被成功接收并处理
3**
重定向,需要进一步的操作以完成请求
4**
客户端错误,请求包含语法错误或无法完成请求
5**
服务器错误,服务器在处理请求的过程中发生了错误
如何封装接口响应状态码
package com.zhaoli.controller;
import java.util.HashMap;
public class BaseController {
/**
* @param code code为200处理成功 为500 处理失败
* @param msg 响应错误内容
* @param data 响应的数据
* @return
*/
public HashMap<String, Object> setResult(Integer code, String msg, Object data) {
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("code", code);
result.put("msg", msg);
result.put("data", data);
return result;
}
/**
* 提供处理请求响应成功的情况下(查询)
*/
public HashMap<String, Object> setResultOk(Object data) {
return setResult(200, "ok", data);
}
/**
* 提供处理请求响应成功的情况下(删除、修改、插入)
*/
public HashMap<String, Object> setResultSuccess(String msg) {
return setResult(200, msg, null);
}
/**
* 提供处理请求响应失败的情况下
*/
public HashMap<String, Object> setResultError(String msg) {
return setResult(500, msg, null);
}
}
package com.zhaoli.controller;
import com.zhaoli.entity.UserEntity;
import com.zhaoli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
/**
* 标记该类是为 SpringMVC控制类
* 在该类中定义的接口都是返回 json 数据
*/
@RestController
@RequestMapping("/user02")
public class UserController02 extends BaseController{
@Autowired
private UserService userService;
/**
* 根据id查询数据
*/
@GetMapping("/getById/{id}")
public HashMap<String, Object> getById(@PathVariable("id") Integer id) {
if(id==null){
return setResultError("id is null");
}
UserEntity user = userService.getById(id);
if (user==null){
return setResultError("根据此id:"+id+"没有查询到数据");
}
return setResultOk(user);
}
/**
* 修改数据
*/
@PutMapping("/update")
public HashMap<String, Object> update(@RequestBody UserEntity userEntity) {
return userService.update(userEntity)>0?setResultSuccess("修改成功"):setResultError("修改失败");
}
/**
* 根据 id 删除数据
*/
@DeleteMapping("/deleteById/{id}")
public HashMap<String, Object> deleteById(@PathVariable("id") Integer id) {
if(id==null){
return setResultError("id is null");
}
return userService.deleteById(id)>0?setResultSuccess("删除成功"):setResultError("删除失败");
}
/**
* 新增数据
*/
@PostMapping("/insertUser")
public HashMap<String, Object> insertUser(@RequestBody UserEntity userEntity) {
return userService.insertUser(userEntity)>0?setResultSuccess("新增成功"):setResultError("新增失败");
}
}
4.4 整合全局捕获异常
当系统发生错误时,统一将系统错误日志 返回输出
package com.mayikt.controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler extends BaseController {
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map<String, Object> handleException(HttpServletRequest h, Exception e) {
System.out.println("自定义异常:" + e);
return setResultError("系统发生了错误!");
}
}