下载、在线预览图片涉及的http.header 以及 关于http.header的网站

以下是介绍有关上传图片所涉及的http.header,如果小伙伴有兴趣了解更多的http的信息,可以点击最下面的腾讯云社区链接。

下载图片

下载图片所涉及的http.header主要有四个,分别为Content-Disposition,Content-Type, Content-length, Connection。

Content-Disposition

响应标头是指示内容是否预期在浏览器中内联显示的标题,即,作为网页或作为网页的一部分或作为附件下载并且本地保存。

Content-Disposition有两个值。

Content-Disposition:inline(默认值,表示它可以显示在网页内,或作为网页)
Content-Disposition:attachment(表示它应该下载)

这里主要讲 attachment
大多数浏览器下载图片呈现“另存为”对话框,预先填入filename如果存在参数的值。

Content-Disposition:attachment;filename="filename.jpg"

Content-Type

Content-Type实体头用于指示所述媒体类型的资源的,如果是图片的话,类型有image/jpeg, image/png, image/gif等等。

Content-Type:image/jpeg

Content-length

Content-Length实体报头指示该实体主体的大小,以字节为单位的十进制数,发送到接收方。

Content-length:1024

Connection

一般 header 控制网络连接是否保持打开状态,当前事务结束之后。如果发送的值是keep-alive,连接是持久的并且不关闭,从而允许对同一服务器的后续请求完成。

一般下载图片都是设置在下载完后就关闭。

Connection:close

在线显示文件

和上面大体相同,就是这里不一样

Content-Disposition:filename="filename.jpg"

就是在Content-Disposition不需要填入attachment。

下面直接上代码

package com.lijun.spring.boot.domain;

import org.bson.types.Binary;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;
import java.util.Objects;

@Document
public class File {
    @Id
    private String id;
    private String name;        //文件名称
    private String contentType; //文件类型
    private Long size;          //文件大小
    private Date uploadDate;    //上传时间
    private String md5;         //计算文件MD5,判断文件是否相同
    private Binary content;     //文件内容
    private String path;        //文件路径

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public Long getSize() {
        return size;
    }

    public void setSize(Long size) {
        this.size = size;
    }

    public Date getUploadDate() {
        return uploadDate;
    }

    public void setUploadDate(Date uploadDate) {
        this.uploadDate = uploadDate;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }

    public Binary getContent() {
        return content;
    }

    public void setContent(Binary content) {
        this.content = content;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public File(String name, String contentType, Long size, Binary content) {
        this.name = name;
        this.contentType = contentType;
        this.size = size;
        this.uploadDate=new Date();
        this.content = content;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        File file = (File) o;
        return Objects.equals(id, file.id) &&
                Objects.equals(name, file.name) &&
                Objects.equals(contentType, file.contentType) &&
                Objects.equals(size, file.size) &&
                Objects.equals(uploadDate, file.uploadDate) &&
                Objects.equals(md5, file.md5) &&
                Objects.equals(content, file.content) &&
                Objects.equals(path, file.path);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, contentType, size, uploadDate, md5, content, path);
    }

    @Override
    public String toString() {
        return "File{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", contentType='" + contentType + '\'' +
                ", size=" + size +
                ", uploadDate=" + uploadDate +
                ", md5='" + md5 + '\'' +
                ", content=" + content +
                ", path='" + path + '\'' +
                '}';
    }
}

package com.lijun.spring.boot.repository;

import com.lijun.spring.boot.domain.File;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface FileRepository extends MongoRepository<File,String> {
}
package com.lijun.spring.boot.service;

import com.lijun.spring.boot.domain.File;

import java.util.List;
import java.util.Optional;

public interface FileService {
    /*
    * 保存文件
    * */
    File saveFile(File file);

    /*
     * 批量保存文件
     * */
    List<File> saveFiles(List<File> uploadFiles);

    /*
    * 删除文件
    * */
    void removeFile(String id);

    /*
    * 根据id获取文件
    * */
    Optional<File> getFileById(String id);

    /*
    * 分页查询,按上传时间降序
    * */
    List<File> listFileByPage(int pageIndex,int pageSize);
}
package com.lijun.spring.boot.service;

import com.lijun.spring.boot.domain.File;
import com.lijun.spring.boot.repository.FileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private FileRepository fileRepository;

    @Override
    public File saveFile(File file) {
        return fileRepository.save(file);
    }

    @Override
    public List<File> saveFiles(List<File> uploadFiles) {
        return fileRepository.saveAll(uploadFiles);
    }

    @Override
    public void removeFile(String id) {
        fileRepository.deleteById(id);
    }

    @Override
    public Optional<File> getFileById(String id) {
        return fileRepository.findById(id);
    }

    @Override
    public List<File> listFileByPage(int pageIndex, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.DESC, "uploadDate");
        Pageable pageable = PageRequest.of(pageIndex, pageSize, sort);

        Page<File> page = fileRepository.findAll(pageable);
        List<File> list = page.getContent();
        return list;
    }
}
package com.lijun.spring.boot.controller;

import com.alibaba.fastjson.JSON;
import com.lijun.spring.boot.domain.File;
import com.lijun.spring.boot.service.FileService;
import com.lijun.spring.boot.util.MD5Util;
import org.bson.types.Binary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@CrossOrigin(origins = "*",maxAge = 3600)   //允许所有域名访问
@Controller
@RequestMapping("/files")
public class FileController {

    @Autowired
    private FileService fileService;

    @Value("${server.address}")
    private String serverAddress;

    @Value("${server.port}")
    private String serverPort;

    /*
    * 显示最新二十条数据
    * */
    @GetMapping
    public String index(Model model,@RequestParam(value="async",required=false) boolean async){
        List<File> files = fileService.listFileByPage(0, 20);
        model.addAttribute("files",files);
        if(async==true){
            return "index :: #fileTable";
        }
        return "index";
    }

    /*
    * 分页查询文件
    * */
    @GetMapping("/{pageIndex}/{pageSize}")
    @ResponseBody
    public List<File> listFileByPage(@PathVariable int pageIndex,@PathVariable int pageSize){
        return fileService.listFileByPage(pageIndex, pageSize);
    }

    /*
    * 获取文件片信息
    *  Content-Disposition 响应标头是指示内容是否预期在浏览器中内联显示的标题,即,作为网页或作为网页的一部分或作为附件下载并且本地保存。
     *                       如果使下载文件的话,语法就是"attachment(附件)":"fileName"=value
    *                       attachment(表示它应该下载;大多数浏览器呈现“另存为”对话框,预先填入filename如果存在参数的值)
    *
    * application/octet-stream 只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)
    *                           ( 二进制流,不知道下载文件类型),例如前端下载图片我们不知道图片的后缀是jpg或jpeg或icon就可以用这个
    * */
    @GetMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Object>  FileMessage(@PathVariable String id) throws UnsupportedEncodingException {
        Optional<File> file = fileService.getFileById(id);  //自定义查找图片,这个根据个人来实现
        if(file.isPresent()){
            /*这里才是核心的部分*/
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=\""+new String(file.get().getName().getBytes("utf-8"),"ISO-8859-1")+"\"")
//                    .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
                    .header(HttpHeaders.CONTENT_TYPE, file.get().getContentType())
                    .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize()+"")
                    .header(HttpHeaders.CONNECTION, "close")
                    .body(file.get().getContent().getData());
        }else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("file was not found");
        }
    }

    /*
    * 在线显示文件
    * CONTENT_DISPOSITION这个可以不写,返回去的就是没有文件名而已
    * HttpHeaders.CONTENT_TYPE这个要写,不然返回去浏览器解析不出这是个图片
    * */
    @GetMapping("/view/{id}")
    public ResponseEntity<Object> serveFileOnline(@PathVariable String id){
        Optional<File> file = fileService.getFileById(id);
        if(file.isPresent()){
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\""+file.get().getName()+"\"")
                    .header(HttpHeaders.CONTENT_TYPE, file.get().getContentType())
                    .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize()+"")
                    .header(HttpHeaders.CONNECTION, "close")
                    .body(file.get().getContent().getData());
        }else{
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("file was not found");
        }
    }

    /*
    * 上传
    * RedirectAttributes 是Spring mvc 3.1版本之后出来的一个功能,专门用于重定向之后还能带参数跳转的的工具类
    * */
    @PostMapping
    public String handleFileUpload(@RequestParam("file")MultipartFile file, RedirectAttributes redirectAttributes){
        try{
            File f = new File(file.getOriginalFilename(), file.getContentType()
                    , file.getSize(), new Binary(file.getBytes()));
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            fileService.saveFile(f);
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            redirectAttributes.addFlashAttribute("mesasge","Your "+file.getOriginalFilename()+"is wrong");  //; 这种方法是隐藏了参数,链接地址上不直接暴露
            return "redirect:/files";
        }
//        redirectAttributes.addFlashAttribute("message", "You successfully upload "+file.getOriginalFilename()+"!");
        redirectAttributes.addFlashAttribute("message", "成功上传文件 "+file.getOriginalFilename()+"!");
        return "redirect:/files";
    }

    /*
     * 批量上传
     * */
    @PostMapping("/uploadFiles")
    public String handleFilesUpload(@RequestParam("file")MultipartFile files[], RedirectAttributes redirectAttributes){
        ArrayList<MultipartFile> list=new ArrayList<>(Arrays.asList(files));
        try{
            ArrayList<File> uploadFiles=new ArrayList<>();
            for (MultipartFile file: list) {
                File f=new File(file.getOriginalFilename(), file.getContentType()
                        , file.getSize(), new Binary(file.getBytes()));
                f.setMd5(MD5Util.getMD5(file.getInputStream()));
                uploadFiles.add(f);
            }
            fileService.saveFiles(uploadFiles);
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            redirectAttributes.addFlashAttribute("mesasge","批量上传失败");  //; 这种方法是隐藏了参数,链接地址上不直接暴露
            return "redirect:/files";
        }
        redirectAttributes.addFlashAttribute("message", "成功上传 "+list.size()+"个文件!");
        return "redirect:/files?async=true";
    }

    /*
    * 上传接口
    * */
    @PostMapping("/upload")
    @ResponseBody
    public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file,@RequestParam("username") String username){
        try{
//            File f=new File(file.getOriginalFilename(),file.getContentType()
//                    ,file.getSize(),new Binary(file.getBytes()));
            File f=new File(file.getOriginalFilename()+"_"+username,file.getContentType()
                    ,file.getSize(),new Binary(file.getBytes()));
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            File returnFile=fileService.saveFile(f);
            String path="//"+serverAddress+":"+serverPort+"/files/view/"+returnFile.getId();
            System.out.println(path);
            return ResponseEntity.status(HttpStatus.OK).body(path);
        }catch (IOException | NoSuchAlgorithmException e){
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    /*编辑博客的上传接口*/
    @PostMapping("/blogUpload/{username}")
    @ResponseBody
    public ResponseEntity<String> blogUpload(@RequestParam("file") MultipartFile file,@PathVariable(value = "username") String username){
        try{
//            File f=new File(file.getOriginalFilename(),file.getContentType()
//                    ,file.getSize(),new Binary(file.getBytes()));
            File f=new File(username+'_'+file.getOriginalFilename(),file.getContentType()
                    ,file.getSize(),new Binary(file.getBytes()));
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            File returnFile=fileService.saveFile(f);
            String path="//"+serverAddress+":"+serverPort+"/files/view/"+returnFile.getId();
            System.out.println(path);
            return ResponseEntity.status(HttpStatus.OK).body(path);
        }catch (IOException | NoSuchAlgorithmException e){
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    /*
     * 批量上传接口
     * */
    @PostMapping("/uploads")
    @ResponseBody
    public ResponseEntity<String> handleFileUploads(@RequestParam("file")MultipartFile files[]){
        ArrayList<MultipartFile> list=new ArrayList<>(Arrays.asList(files));
        try{
            ArrayList<File> uploadFiles=new ArrayList<>();
            for (MultipartFile file: list) {
                File f=new File(file.getOriginalFilename(), file.getContentType()
                        , file.getSize(), new Binary(file.getBytes()));
                f.setMd5(MD5Util.getMD5(file.getInputStream()));
                uploadFiles.add(f);
            }
            List<File> returnFiles=fileService.saveFiles(uploadFiles);
            ArrayList<String> urlList=new ArrayList<>();
            for (File f: returnFiles) {
                urlList.add("//"+serverAddress+":"+serverPort+"/files/view/"+f.getId());
            }
            String urls = JSON.toJSONString(urlList);
            System.out.println(urls);
            return ResponseEntity.status(HttpStatus.OK).body(urls);
        }catch (IOException | NoSuchAlgorithmException e){
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    /*
    * 删除文件
    * */
    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<String> deleteFile(@PathVariable String id){
        try{
            fileService.removeFile(id);
            return ResponseEntity.status(HttpStatus.OK).body("delete_success");
        }catch (Exception e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }
}

<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb</artifactId>
		</dependency>
		<!--<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongodb-driver-sync</artifactId>
			<version>4.0.0-beta1</version>
		</dependency>
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
		</dependency>-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.41</version>
		</dependency>

	</dependencies>

腾讯云社区

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值