在看别人的一个开源工程时,有段代码引起了我的疑惑:
/**
* 下载
* @param file 文件
* @param fileName 生成的文件名
* @return {ResponseEntity}
*/
protected ResponseEntity<Resource> download(File file, String fileName) {
Resource resource = new FileSystemResource(file);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
String header = request.getHeader("User-Agent");
// 避免空指针
header = header == null ? "" : header.toUpperCase();
HttpStatus status;
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
fileName = URLUtils.encodeURL(fileName, Charsets.UTF_8);
status = HttpStatus.OK;
} else {
fileName = new String(fileName.getBytes(Charsets.UTF_8), Charsets.ISO_8859_1);
status = HttpStatus.CREATED;
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<Resource>(resource, headers, status);
}
在if-else的代码中对HttpStatus的设置值HttpStatus.Create有点疑问:对“User-Agent”的获取,只是得到用户客户端浏览器的某些属性信息,跟返回状态有毛线关系啊,这里却根据不同的属性返回不同的httpstatus,很让人费解。
好吧,那就查下资料补补墨水吧。
百度发现Created状态一般是配合PUT请求使用的,参考文章(https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/PUT):
请求方法 PUT 用于新增资源或者使用请求中的有效负载替换目标资源的表现形式。
PUT
与POST
方法的区别在于,PUT方法是幂等的:调用一次与连续调用多次是等价的(即没有副作用),而连续调用多次POST方法可能会有副作用,比如将一个订单重复提交多次。
可以简单理解下,新增一条资源,需要上传资源到服务器,服务器接收到资源后,如果新增成功则返回code201,客户端接收到201后则如果它重复put则无效。从而达到了http的状态统一性(这个词是从博客中学到的)了吧。但是如果我们使用post则是不符合http的状态统一性的,客户端可以重复多次post提交。
综上,本人认为上面的代码是有问题的,在下载接口中设置Created状态纯属无理取闹,毫无意义。至于为什么要写这篇文章呢?是因为公司同事说别人这样写没有问题,她说用360浏览器在访问返回json数据的接口时会提示是否下载保存,而用Chrome浏览器却会直接显示,她说直接显示的就是用的HttpStatus.OK,要选择下载保存的则为HttpStatus.Created,一边说着一边把她打印的各个状态code含义给我看,说“created就是服务器告诉客户端浏览器要保存该文件” ==!,但是本人感觉还是不对,因为她那打印纸上明明写的是服务器上新增资源啊!所以还是深入的查下资料,彻底弄明白~