SpringMVC快速学习
目录
序言
SpringMVC实现步骤
创建配置类
创建Controller类
使用配置类替换web.xml
配置Tomcat环境
浏览器访问
前端传递JSON数据参数
json普通数组
小结
Postman中的Body中的form-data、x-www-form-urlencoded、raw、binary、GraphQL的区别
响应
1.返回文本数据
2.返回POJO对象
前后端传递使用集合传递多个值
Rest风格
Restful风格举例
增
删
改
查询单个
查询所有
总结
@RequestBody、@RequestParam、@PathVariable,这三个注解之间的区别和应用分别是什么?
常见问题
GET请求中文乱码问题
POST请求中文乱码
有前端界面的情况下,访问不到静态页面?
本文只是简单的让大家了解清楚SpringMVC工程的结构和代码,对于细节内容以及一些原理没有详细说明,对于原理部分大家可以学习其他文章。
序言
SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装。
SpringMVC是处于Web层的框架,所以其主要的作用就是用来接收前端发过来的请求和数据,然后经过处理并将处理的结果响应给前端,所以如何处理请求和响应是SpringMVC中非常重要的一块内容。
SpringMVC实现流程是什么?
1.创建web工程(Maven结构)
2.设置tomcat服务器,加载web工程(tomcat插件)
3.导入坐标(SpringMVC+Servlet)
4.定义处理请求的功能类(UserController)
5.设置请求映射(配置映射关系)
6.将SpringMVC设定加载到Tomcat容器中
SpringMVC实现步骤
创建配置类
@Configuration
@ComponentScan("com.uu.controller")
public class SpringMvcConfig {
}
创建Controller类
注意 @RequestMapping("/save")
@ResponseBody 注解的使用
@Controller
public class UserController {@RequestMapping("/save")@ResponseBodypublic String save(){System.out.println("user save ...");return "{'info':'springmvc'}";}
}
使用配置类替换web.xml
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {//加载springmvc配置类protected WebApplicationContext createServletApplicationContext() {//初始化WebApplicationContext对象AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();//加载指定配置类ctx.register(SpringMvcConfig.class);return ctx;}//设置由springmvc控制器处理的请求映射路径protected String[] getServletMappings() {return new String[]{"/"};}//加载spring配置类protected WebApplicationContext createRootApplicationContext() {return null;}
}
配置Tomcat环境
浏览器访问
浏览器输入http://localhost/save
进行访问
知识点1:@Controller
名称 | @Controller |
---|---|
类型 | 类注解 |
位置 | SpringMVC控制器类定义上方 |
作用 | 设定SpringMVC的核心控制器bean |
知识点2:@RequestMapping
名称 | @RequestMapping |
---|---|
类型 | 类注解或方法注解 |
位置 | SpringMVC控制器类或方法定义上方 |
作用 | 设置当前控制器方法请求访问路径 |
相关属性 | value(默认),请求访问路径 |
知识点3:@ResponseBody
名称 | @ResponseBody |
---|---|
类型 | 类注解或方法注解 |
位置 | SpringMVC控制器类或方法定义上方 |
作用 | 设置当前控制器方法响应内容为当前返回值,无需解析 |
-
SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
-
Spring控制的bean
-
业务bean(Service)
-
功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
-
@ComponentScan
名称 | @ComponentScan |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置spring配置类扫描路径,用于加载使用注解格式定义的bean |
相关属性 | excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)和具体项(classes) includeFilters:加载指定的bean,需要指定类别(type)和具体项(classes) |
前端传递JSON数据参数
现在比较流行的开发方式为异步调用。前后台以异步方式进行交换,传输的数据使用的是JSON
对于JSON数据类型,我们常见的有三种:
-
json普通数组(["value1","value2","value3",...])
-
json对象({key1:value1,key2:value2,...})
-
json对象数组([{key1:value1,...},{key2:value2,...}])
json普通数组
1.pom.xml添加jackson依赖
2.开启json数据类型自动转换
3.参数前添加@RequestBody
上面的示例是传递了一个List集合,那对象怎么传递呢
以User举例
访问接口在postman中这样写
如果是多个USer
小结
SpringMVC接收JSON数据的实现步骤为:
(1)导入jackson包
(2)使用PostMan发送JSON数据
(3)开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解
(4)Controller方法的参数前添加@RequestBody注解
知识点1:@EnableWebMvc
名称 @EnableWebMvc 类型 配置类注解 位置 SpringMVC配置类定义上方 作用 开启SpringMVC多项辅助功能 知识点2:@RequestBody
名称 @RequestBody 类型 形参注解 位置 SpringMVC控制器方法形参定义前面 作用 将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次 @RequestBody与@RequestParam区别
区别
@RequestParam用于接收url地址传参,
表单传参【application/x-www-form-urlencoded】 【post请求】
或者直接在Params中输入 【get请求】
@RequestBody用于接收json数据【application/json】
应用
开发中,发送json格式数据为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数
Postman中的Body中的form-data、x-www-form-urlencoded、raw、binary、GraphQL的区别
参考这一篇非常详细
后端 - Postman 的 Body 中的 form-data、x-www-form-urlencoded、raw、binary 的区别 - 个人文章 - SegmentFault 思否
响应
后端接受到数据后,如何给前端相应呢?
对于响应,主要就包含两部分内容:
-
响应页面
-
响应数据
-
文本数据
-
json数据
-
我们主要关注的就是如何返回JSON数据
1.返回文本数据
2.返回POJO对象
使用Postman测试后,返回的情况如下:
这里用到了类型转换,内部是通过Converter接口的实现类完成的。
实现了:
- 对象转Json数据(POJO -> json)
前后端传递使用集合传递多个值
使用@RequestParam行参注解
名称 | @RequestParam |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 绑定请求参数与处理器方法形参间的关系 |
相关参数 | required:是否为必传参数 defaultValue:参数默认值 |
Rest风格
restful的作用就是同意请求url,下面举例说明
-
传统风格资源描述形式
-
http://localhost/user/getById?id=1
查询id为1的用户信息 -
http://localhost/user/saveUser
保存用户信息
-
-
REST风格描述形式
-
http://localhost/user/1
-
http://localhost/user
-
传统方式一般是一个请求url对应一种操作,这样做不仅麻烦,也不安全,因为会程序的人读取了你的请求url地址,就大概知道该url实现的是一个什么样的操作。
-
REST风格访问资源时的接口如下:
-
http://localhost/users
查询全部用户信息 GET(查询) -
http://localhost/users/1
查询指定用户信息 GET(查询) -
http://localhost/users
添加用户信息 POST(新增/保存) -
http://localhost/users
修改用户信息 PUT(修改/更新) -
http://localhost/users/1
删除用户信息 DELETE(删除)
-
可以看到上面的接口访问地址一样,那这怎么区分呢?
按照不同的请求方式代表不同的操作类型。
-
发送GET请求是用来做查询
-
发送POST请求是用来做新增
-
发送PUT请求是用来做修改
-
发送DELETE请求是用来做删除
请求的方式比较多,但是比较常用的就4种,分别是GET
,POST
,PUT
,DELETE
。
Restful风格举例
下面我们按照增删改查的顺序,将原本风格的代码改为Restful风格
增
修改后
删
是不是感觉上图中的delete已经写好了,但是不行哦,这个代码是携带不到数据参数的,
我们要在方法的形参前加上@PathVariable注解
如果需要传递的有多个参数,按照如下格式写
改
修改后
前端往后端传递参数时选择的是Body中的json格式
查询单个
查询所有
总结
使用Restful风格的三个关键点
1)设定Http请求动作(动词)
@RequestMapping(value="",method = RequestMethod.POST|GET|PUT|DELETE)
(2)设定请求参数(路径变量)
@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}
知识点1:@PathVariable
名称 | @PathVariable |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应 |
@RequestBody
、@RequestParam
、@PathVariable
,这三个注解之间的区别和应用分别是什么?
-
区别
-
@RequestParam用于接收url地址传参或表单传参
-
@RequestBody用于接收json数据
-
@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
-
-
应用
-
后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
-
如果发送非json格式数据,选用@RequestParam接收请求参数
-
采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
-
在前面的例子中可以看到,在每一个增删改查的方法上面都需要:
- 每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
- 每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
- 每个方法响应json都需要加上@ResponseBody注解,重复性太高。
对于上面的几个问题,如何解决呢???
每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
将@RequestMapping提到类上面,用来定义所有方法共同的访问路径。
每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替
每个方法响应json都需要加上@ResponseBody注解,重复性太高。
1.将ResponseBody提到类上面,让所有的方法都有@ResponseBody的功能
2.使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
具体的修改代码示例如下图,用红框的内容替换了蓝框的内容。
知识点1:@RestController
名称 | @RestController |
---|---|
类型 | 类注解 |
位置 | 基于SpringMVC的RESTful开发控制器类定义上方 |
作用 | 设置当前控制器类为RESTful风格, 等同于@Controller与@ResponseBody两个注解组合功能 |
知识点2:@GetMapping @PostMapping @PutMapping @DeleteMapping
名称 | @GetMapping @PostMapping @PutMapping @DeleteMapping |
---|---|
类型 | 方法注解 |
位置 | 基于SpringMVC的RESTful开发控制器方法定义上方 |
作用 | 设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作, 例如@GetMapping对应GET请求 |
相关属性 | value(默认):请求访问路径 |
常见问题
GET请求中文乱码问题
omcat8.5以后的版本已经处理了中文乱码的问题,但是IDEA中的Tomcat插件目前只到Tomcat7,所以需要修改pom.xml来解决GET请求中文乱码问题.
POST请求中文乱码
解决方案:配置过滤器
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {protected Class<?>[] getRootConfigClasses() {return new Class[0];}protected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMvcConfig.class};}protected String[] getServletMappings() {return new String[]{"/"};}//乱码处理@Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("UTF-8");return new Filter[]{filter};}
}
有前端界面的情况下,访问不到静态页面?
出现该问题的原因是SpringMVC拦截了静态资源。
解决办法:
在SpringMVC配置类中添加下图中的函数。