1、获取json类型的请求参数
json类型的请求参数一定是在请求体中携带的
{name:value,name:value}类型的参数: vue的post请求,请求头Content-Type的值必然为"application/json"
只能采用封装的形式获取请求参数,封装到POJO中或者Map中
1. POJO的属性名要和请求参数名一致
2. Controller中的方法的参数前添加RequestBody注解
3. 项目中一定要引入jackson的依赖
添加jackson的依赖,因为Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要添加jackson依赖。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
@RequestBody
@RequestBody等注解见上篇
1、以String 类型获取请求体的内容
@RequestMapping("/useBody")
public String useRequestBody(@RequestBody String body){
//目标: 使用body参数来获取请求体的内容----->从请求体中获取参数
System.out.println("请求体的内容是:" + body);
return "success";
}
postman发送json:
2、以POJO或Map 类型获取请求体的内容
@Data
public class User implements Serializable {
private String username;
private String password;
private String nickname;
//@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
private List<String> hobbies;
}
@RequestMapping("/useJson")
public String useJson(@CookieValue("") User user, HttpSession session){
session.setAttribute("age", 19);
//目标: 使用body参数来获取请求体的内容----->从请求体中获取参数
System.out.println("请求体的内容是:" + user);
return "success";
}
2、获取路径参数
请求参数作为请求路径的一部分。路径参数适合用于有层级关系的参数
2.1 RESTFul 风格 URL
1、可以携带路径参数
2、一个路径代表一个资源
REST(英文: Representational State Transfer,简称 REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种 Web 服务交互方案中, REST 相比于 SOAP(Simple Object Access protocol,简单对象访问协议)以及 XML-RPC 更加简单明了,无论是对 URL 的处理还是对 Payload 的编码, REST 都倾向于用更加简单轻量的方法设计和实现。值得注意的是 REST 并没有一个明确的标准,而更像是一种设计的风格。它本身并没有什么实用性,其核心价值在于如何设计出符合 REST 风格的网络接口。
-
restful 的优点
它结构清晰、符合标准、易于理解、 扩展方便,所以正得到越来越多网站的采用。
-
restful 的特性:
资源(Resources) : 网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI 就可以,因此 URI 即为每一个资源的独一无二的识别符。
表现层(Representation) : 把资源具体呈现出来的形式,叫做它的表现层 (Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、 XML 格式、 JSON 格式表现,甚至可以采用二进制格式。
状态转化(State Transfer) : 每 发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP 协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段, 让服务器端发生“ 状态转化” (State Transfer)。而这种转化是建立在表现层之上的,所以就是 “ 表现层状态转化” 。具体说,就是 HTTP 协议里面,四个表示操作方式的动词: GET 、 POST 、 PUT、DELETE。它们分别对应四种基本操作: GET 用来获取资源, POST 用来新建资源, PUT 用来更新资源, DELETE 用来删除资源 . -
实例
保存
传统:http://localhost:8080/user/save
REST:http://localhost:8080/user POST方式 执行保存
更新
传统:http://localhost:8080/user/update?id=1
REST:http://localhost:8080/user/1 PUT方式 执行更新 1代表id
删除
传统:http://localhost:8080/user/delete?id=1
REST:http://localhost:8080/user/1 DELETE方式 执行删除 1代表id
查询
传统:http://localhost:8080/user/findAll
REST:http://localhost:8080/user GET方式 查所有
传统:http://localhost:8080/user/findById?id=1
REST:http://localhost:8080/user/1 GET方式 根据id查1个
2.2 @PathVariable
该注解的作用是,获取RestFul风格的url上的参数
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
@AliasFor("name")
String value() default "";
/**
* The name of the path variable to bind to.
*/
@AliasFor("value")
String name() default "";
/**
* Whether the path variable is required.
*/
boolean required() default true;
}
2.2.1 使用说明
-
作用:
用于绑定 url 中的占位符。 例如:请求 url 中 /delete/{id}, 这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。 -
属性:
value: 用于指定 url 中占位符名称。
required:是否必须提供占位符。
2.2.2 使用实例
UserController
/**
* .../findCheckItem?mealId=1&groupId=3&itemId=10
* 目标: /套餐id/检查组的id/检查项的id ----> .../1/3/10
* @return
*/
@RequestMapping(method = RequestMethod.GET,path = "/{mealId}/{groupId}/{itemId}")
public String findCheckItem(@PathVariable("mealId") int mealId,
@PathVariable("groupId") int groupId,
@PathVariable("itemId") int itemId){
System.out.println("根据id查询:mealId=" + mealId + ",groupId=" + groupId +
",itemId=" + itemId);
return "success";
}
@RequestMapping(method = RequestMethod.DELETE,path = "/{mealId}/{groupId}/{itemId}")
public String deleteCheckItem(@PathVariable("mealId") int mealId,
@PathVariable("groupId") int groupId,
@PathVariable("itemId") int itemId){
System.out.println("根据id删除:mealId=" + mealId + ",groupId=" + groupId +
",itemId=" + itemId);
return "success"; //delete不能这样打印
}
- postman访问
- http://localhost:8080/user/1/11/13 使用delete请求测试
- http://localhost:8080/user/1/11/13 使用get请求测试
@PathVariable注解允许参数为空、允许不传参数的问题
java+中path注解_@Pathvariable注解允许参数为空吗?
3、响应数据和结果视图
3.1 字符串
controller 方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
@Controller
@RequestMapping("/response")
public class ResponseController {
//指定逻辑视图名,经过视图解析器解析为 jsp 物理路径: /WEB-INF/pages/success.jsp
@RequestMapping("/testReturnString")
public String testReturnString(){
System.out.println("testReturnString");
return "success";
}
}
3.2 ModelAndView
ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值。 jsp中
@RequestMapping("testReturnModelAndView")
public ModelAndView testReturnModelAndView() {
ModelAndView mv = new ModelAndView();//数据模型和视图
//ModelAndView对象既能够绑定视图名字,又能够绑定数据(将数据存储到request域对象)
mv.addObject("name","张三");
mv.addObject("age",18);
mv.setViewName("success");
//去找视图解析器,解析viewName,使用请求转发跳转到对应的视图
return mv;
}
前后端分离后,用不到域对象了,不存在请求转发和重定向
4、请求转发和重定向
4.1 forward 转发
controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。我们也可以加上 forward:
可以转发到页面,也可以转发到其它的controller方法
转发到页面
需要注意的是,如果用了 forward: 则路径必须写成实际视图 url,不能写逻辑视图。它相当于“request.getRequestDispatcher(“url”).forward(request,response)”
//转发到页面
@RequestMapping("forwardToPage")
public String forwardToPage(){
System.out.println("forwardToPage...");
//请求转发,不需要视图解析器
return "forward:/WEB-INF/pages/success.jsp";
}
转发到其它的controller方法
语法: forward:/类上的RequestMapping/方法上的RequestMapping
//转发到其它controller
@RequestMapping("forwardToOtherController")
public String forwardToOtherController(){
System.out.println("forwardToOtherController...");
return "forward:/response/testReturnModelAndView";
}
4.2 Redirect 重定向
contrller 方法提供了一个 String 类型返回值之后, 它需要在返回值里使用: redirect:
同样可以重定向到页面,也可以重定向到其它controller
重定向到页面
它相当于“response.sendRedirect(url)” 。需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。
//重定向到页面
@RequestMapping("redirectToPage")
public String redirectToPage(){
System.out.println("redirectToPage...");
return "redirect:/redirect.jsp";
}
重定向到其它的controller方法
语法: redirect:/类上的RequestMapping/方法上的RequestMapping
//重定向到其它Controller
@RequestMapping("redirectToOtherController")
public String redirectToOtherController(){
System.out.println("redirectToOtherController...");
return "redirect:/response/testReturnModelAndView";
}
转发和重定向区别
- 转发是一次请求, 重定向是两次请求
- 转发路径不会变化, 重定向的路径会改变
- 转发只能转发到内部的资源,重定向可以重定向到内部的(当前项目里面的)也可以是外部的(项目以外的)
- 转发可以转发到web-inf里面的资源, 重定向不可以重定向到web-inf里面的资源
4.3 ResponseBody响应 json数据(重点)
@ResponseBody
该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如: json,xml 等,通过 Response 响应给客户端
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要添加jackson依赖。
- 导入jackson坐标
- 把什么对象转json, 方法返回值就定义什么类型
- 添加@ResponseBody注解
@RequestMapping("/responseJson")
@ResponseBody //如果不加该注解,则找@RequestMapping中类和方法合成的视图
public User responseJson(){
//模拟从数据库查询数据
User user = new User();
user.setUsername("周杰伦");
user.setPassword("123456");
user.setNickname("双节棍");
user.setBirthday(new Date());
List<String> hobbiesList = new ArrayList<>();
hobbiesList.add("basketball");
hobbiesList.add("football");
user.setHobbies(hobbiesList);
//将user转换成json响应给客户端
return user;
}
可以在方法上添加ResponseBody注解
可以在类上添加ResponseBody注解
可以将Controller注解改成RestController注解
在方法上面或者方法的返回值前面添加@ResponseBody
解决DispatcherServlet拦截静态资源的问题
方式一(不常用): DispatcherServlet如果配置映射路径为"/"会拦截到所有的资源(除了JSP),导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截.
语法: <mvc:resources location="/css/" mapping="/css/**"/>
, location:webapp目录下的包,mapping:匹配请求路径的格式
在springmvc.xml配置文件添加如下配置
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
方式二:让DefaultServlet去处理静态资源,DispatcherServlet就不处理静态资源了
<mvc:default-servlet-handler />
mvc:default-servlet-handler标签的作用
方式三:改变DispatcherServlet的映射路径,改成"*.do"
@CrossOrigin
1、跨域的基本概念
a、跨域的解释
要了解跨域,首先需要知晓浏览器的同源策略,简单的说就是两个请求协议、端口、主机都相同,则两个请求具有相同的源,可以自由访问。下表以http://store.company.com/dir/page.html为例,进行一些 url 的同源检测:
浏览器的同源策略控制了不同源之间的交互,也就出现了跨域的问题,对于为什么引入同源策略,官方给出的解释是 “同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。”浏览器的同源策略在一定程度上能规避一些危险、提高攻击的成本。
b、跨域问题的解决
JSONP: 这种解决跨域问题的方式前后端都需要有改动,在此不做介绍。
CORS: 一个W3C标准,全程跨域资源共享 (Cross-Origin Resource Sharing),本文也主要讲解该种解决方式。