RestFul
Restful就是一个资源定位、资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
资源:互联网所有的事物都可以被抽象为资源
资源操作:分为POST、DELETE、PUT、GET四种方法,使用不同方法对资源进行操作(增、删、改、查)
HTTP方法 | 说明 |
---|---|
POST | 一般做新增 |
GET | 读取操作 |
PUT | 更新操作 |
DELETE | 删除操作 |
Restful:可以对相同的请求路径,不同的请求方式,做不同的操作处理
具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE用来删除资源。
REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。
传统的与RestFul区别
传统方式操作资源
通过不同的参数来实现不同的效果!方法单一!
http://127.0.0.1/item/queryItem.action?id=1 (查询,GET)
http://127.0.0.1/item/saveItem.action (新增,POST)
http://127.0.0.1/item/updateItem.action (更新,POST)
http://127.0.0.1/item/deleteItem.action?id=1 (删除,GET或POST)
RestFul方式操作资源
可以通过不同的请求方式来实现不同的效果!
如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1 (查询,GET)
http://127.0.0.1/item (新增,POST)
http://127.0.0.1/item (更新,PUT)
http://127.0.0.1/item/1 (删除,DELETE)
RestFul
可以根据请求方式来进行选择不同的处方式,SpringMVC支持Restful模式
RestFul的请求传值方式也是不一样的。路径中通过多个/进行值对应
示例
//观察Get方式的请求形式
@GetMapping("/restfulTest/{str}")
public String restfulGet(@PathVariable("str")String strvalue, Map<String,Object>map){
map.put("str",strvalue);
System.out.println("get");
return "show";
}
@PostMapping("/restfulTest")
public String restfulPost(Map<String,Object>map){
map.put("str","post");
System.out.println("post");
return "show";
}
@PutMapping("/restfulTest")
public String restfulPut(Map<String,Object>map){
map.put("str","put");
System.out.println("put");
return "show";
}
@DeleteMapping("/restfulTest")
public String restfulDelete(Map<String,Object>map){
map.put("str","delete");
System.out.println("delete");
return "show";
}
curl http://localhost:8080/restfulTest/
curl -X POST http://localhost:8080/restfulTest/
curl -X PUT http://localhost:8080/restfulTest/
curl -X DELETE http://localhost:8080/restfulTest/
相同的请求,不同的请求方式,不同的结果
HttpMessageConverter
HttpMessageConverter,报文信息转换器
将请求报文转换为Java对象
或将Java对象转换为响应报文
HttpMessageConverter提供了两个注解和两个类型:
@RequestBody,@ResponseBody, RequestEntity, ResponseEntity
@RequestBody
@RequestBody可以获取请求体,需要在控制器方法设置一个形参
@RequestBody进行标识,当 前请求的请求体就会为当前注解所标识的形参赋值
这里因为是在请求体中获取参数。所以需要使用post提交方式。并且带入参数
@RequestMapping(value = "bodyTest",method = RequestMethod.POST)
public String RequestBodyTest(@RequestBody String str){
System.out.println("requestbody:"+str);
return "show";
}
@RequestEntity
RequestEntity封装请求报文的一种类型,需要在控制器方法的形参中设置该类型的形参,当前请求的 请求报文就会赋值给该形参
可以通getHeaders()获取请求头信息,通过getBody()获取请求体信息
使用起来同@RequestBody一致
@RequestBody
@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到 浏览器
直接将返回值作为响应体进行展示
SpringMvc处理JSON
如果通过@ResponseBody注解想要返回对象,通过json展示
这里说明之后的SpringBoot默认@RequestBody就是返回JSON形式
导入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
//SpringMVC配置文件中进行指定
<mvc:annotation-driven />
@RestController注解
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上
就相当于为类添加了 @Controller注解,并且为其中的每个方法添加了@ResponseBody注解
@ResponseEntity
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文
主要用来操作文件的上传下载
文件上传和下载
我们在学习javaIO的时候,经常在文件的读取和写入之间做操作。
从而达到文件的复制功能,这里的文件上传其实就是文件的复制
将文件从服务器端复制到浏览器端就是文件下载
将文件从浏览器端复制到服务器端就是文件的上传
之后,文件都是保存在数据库中。请求过去,通过路径获取到指定的文件。将文件通过IO解析成byte[],等信息。进行传输,从而在进行转换。
文件下载
我们这里将文件放入web模块中的图片文件夹,方便我们进行获取
编写主要的文件下载代码
这里指定的文件路径在之后肯定是通过动态的参数来填入的
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/zm.png");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=zm.png");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
文件上传
页面的要求
文件上传要求form表单的请求方式必须为post,并且添加属性enctype=“multipart/form-data” SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
<form action="/testUp" method="post" enctype="multipart/form-data">
<%--这里指定文件的域的name属性,方便在multipart中获取--%>
选择文件:<input type="file" name="photo">
<button type="submit">上传文件</button>
</form>
添加依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
SpringMVC引入文件文件上传解析器
<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
代码操作
@RequestMapping("/testUp")
// MultipartFile封装了文件上传功能,操作起来更加简洁
public String testUp(MultipartFile photo, HttpSession session) throws
IOException {
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
String hzName = fileName.substring(fileName.lastIndexOf("."));
// 为了避免上传的文件都是同名导致文件的覆盖
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if(!file.exists()){
file.mkdir();
}
String finalPath = photoPath + File.separator + fileName;
//实现上传功能
photo.transferTo(new File(finalPath));
return "success";
}
注意HTML的表单一定要注意