zoukankan      html  css  js  c++  java
  • 15、SpringBoot实现Excel的导入导出

    前言

    需求:正如标题所言,需求有数据的导入、导出

    导入:给用户提供给一个导入数据的模板,用户填写数据后上传,实现文件的批量导入。

    导出:将数据列表直接导进excel,用户通过浏览器下载。

    首先考虑用经典的apache poi实现这一功能,但是发现不是很好用,后面有换了阿里的 easy excel,效率比较高。

    如果需求不高,只是简单的导入导出,不涉及复杂对象,可以直接使用第一版的代码。

    excel基本构成

    虽然只写个导入导出并不要求我们对excel有多熟悉,但是最起码得知道excel有哪些构成。

    整个文件:student.xlsx,对应与poi中的Workbook

    sheet:一张表

     cell:单元格,每一小格

    apache poi

    依赖

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.apache.poi/poi 03版的excel -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.2</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml 新版的excel -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

    实体类

    @Data
    @AllArgsConstructor
    public class Student {
        private String name;
    
        private Integer age;
    
        private String hobby;
    
        private Float score;
    
        private Date birth;
    }

    读取

    HSSF开头是老版本的excel,拓展名为xls

    我们这里用的是新版本得,拓展名xlsx

    public class TestRead {
    
        public static void main(String[] args) throws IOException {
            XSSFWorkbook workbook = new XSSFWorkbook("E:\personcode\office-learn\src\main\resources\excel\test.xlsx");
    
            XSSFSheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                for (Cell cell : row) {
                    System.out.print(cell.toString() +"	");
                }
                System.out.println();
            }
    
            workbook.cloneSheet(0);
        }
    }

    写入

    public class TestWrite {
    
        public static List<Student> getStudentList() {
            return Arrays.asList(
                    new Student("学生1", 18, "学习", 59.5F, new Date()),
                    new Student("学生2", 19, "游泳", 68F, new Date()),
                    new Student("学生3", 19, "游泳", 90F, new Date()),
                    new Student("学生4", 19, "游泳", 100F, new Date())
            );
        }
    
        public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    
        public static void main(String[] args) throws IllegalAccessException {
            //创建一个表格
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
            List<Student> studentList = getStudentList();
            //创建一个sheet
            XSSFSheet sheet = xssfWorkbook.createSheet("学生成绩");
    
            //单元格格式
            XSSFCellStyle cellStyle = xssfWorkbook.createCellStyle();
            cellStyle.setFillBackgroundColor(IndexedColors.PINK.getIndex());
    
    
            //字体样式
            XSSFFont font = xssfWorkbook.createFont();
            font.setFontName("黑体");
            font.setColor(IndexedColors.BLUE.getIndex());
            cellStyle.setFont(font);
    
    
            //设置第一行
            XSSFRow row = sheet.createRow(0);
            row.createCell(0).setCellValue("姓名");
            row.createCell(1).setCellValue("年龄");
            row.createCell(2).setCellValue("兴趣");
            row.createCell(3).setCellValue("分数");
            row.createCell(4).setCellValue("日期");
    
            for (int i = 1; i < studentList.size(); i++) {
                Student student = studentList.get(i);
                XSSFRow xrow = sheet.createRow(i);
                //如果不设置格式
    //            xrow.createCell(0).setCellValue(student.getName());
    //            xrow.createCell(1).setCellValue(student.getAge());
    //            xrow.createCell(2).setCellValue(student.getHobby());
    //            xrow.createCell(3).setCellValue(student.getScore());
    //            xrow.createCell(4).setCellValue(student.getBirth());
                XSSFCell cell1 = xrow.createCell(0);
                cell1.setCellValue(student.getName());
                cell1.setCellStyle(cellStyle);
    
                XSSFCell cell2 = xrow.createCell(1);
                cell2.setCellValue(student.getAge());
                cell2.setCellStyle(cellStyle);
    
                XSSFCell cell3 = xrow.createCell(2);
                cell3.setCellValue(student.getHobby());
                cell3.setCellStyle(cellStyle);
    
                XSSFCell cell4 = xrow.createCell(3);
                cell4.setCellValue(student.getScore());
                cell4.setCellStyle(cellStyle);
    
                XSSFCell cell5 = xrow.createCell(4);
                cell5.setCellValue(format.format(student.getBirth()));
                cell5.setCellStyle(cellStyle);
    
    
    
            }
    
            //获取样式
    //        XSSFCellStyle cellStyle = xssfWorkbook.createCellStyle();
    //        XSSFDataFormat format = xssfWorkbook.createDataFormat();
    //        cellStyle.setDataFormat(format.getFormat("yyyy年m月d日"));
    
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream("E:\personcode\office-learn\src\main\resources\excel\student.xlsx");
                xssfWorkbook.write(fileOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    xssfWorkbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

     Easy Excel

    我们先用简单的数据结构测试一下,能跑起来才是王道,然后再考虑集成进SpringBoot,以及复杂数据。

    依赖

    spring之类的依赖就不赘述了

            <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>2.2.6</version>
            </dependency>

    实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor //如果加上面一个注解,这个必须加上,否则easy excel会报无法实例化
    public class Student {
    
        @ExcelProperty("姓名")
        private String name;
    
        @ExcelProperty("年龄")
        private Integer age;
    
        @ExcelProperty("爱好")
        private String hobby;
    
        @ExcelProperty("分数")
        private Float score;
    
        @ExcelProperty("生日")
        private Date birth;
    }

    简单写入

    public class TestWrite {
    
        public static List<Student> getStudentList() {
            return Arrays.asList(
                    new Student("学生1", 18, "学习", 59.5F, new Date()),
                    new Student("学生2", 19, "游泳", 68F, new Date()),
                    new Student("学生3", 19, "游泳", 90F, new Date()),
                    new Student("学生4", 19, "游泳", 100F, new Date())
            );
        }
    
        public static void main(String[] args) {
            String fileName = "E:\personcode\office-learn\src\main\resources\excel\student.xlsx";
            // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            // 如果这里想使用03 则 传入excelType参数即可
            EasyExcel.write(fileName, Student.class).sheet("学生信息").doWrite(getStudentList());
        }
    }

    执行结果

    对比POI,有一种从SSM换到了SpringBoot的感觉。

    简单读取

    public class TestRead {
    
        public static void main(String[] args) {
            String fileName = "E:\personcode\office-learn\src\main\resources\excel\student.xlsx";
            // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
            EasyExcel.read(fileName, Student.class, new DemoDataListener()).sheet().doRead();
        }
    }

    简单读取需要配置一个监听类,在这个监听类里处理数据,可以边读取边处理。

    下面监听类的作用是,打印每一行数据

    public class DemoDataListener extends AnalysisEventListener<Student> {
    
        public DemoDataListener() {}
    
        //解析每条数据的时候会调用这个方法
        @Override
        public void invoke(Student student, AnalysisContext analysisContext) {
            System.out.println(student);
        }
    
        //解析完成后调用这个方法
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }

    控制台输出

    Student(name=学生1, age=18, hobby=学习, score=59.5, birth=Wed Nov 11 20:32:20 CST 2020)
    Student(name=学生2, age=19, hobby=游泳, score=68.0, birth=Wed Nov 11 20:32:20 CST 2020)
    Student(name=学生3, age=19, hobby=游泳, score=90.0, birth=Wed Nov 11 20:32:20 CST 2020)
    Student(name=学生4, age=19, hobby=游泳, score=100.0, birth=Wed Nov 11 20:32:20 CST 2020)

    集成进SpringBoot

    在完成基本的导入导出功能后,我们就可以考虑将代码集成进SpringBoot了。

    第一版

    仅仅针对上面的代码,做初步集成,暂不考虑其他需求,例如多个sheet、日期转换等

    既然要继承进Spring环境,我主张完全交给Spring来管理,不要再new对象了。

    依赖

    模拟真实开发环境,需要加入数据库相关的依赖,这里我还是用的mybatis plus:

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>2.2.6</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

    配置文件

    server:
      port: 8080
    
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://ip:3306/test?useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
    
    
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      type-enums-package: com.dayrain.nums
      global-config:
        db-config:
          logic-not-delete-value: 1
          logic-delete-value: 0
    
      mapper-locations: classpath*:/mapper/**/*.xml

    实体类

    与上面相比,添加了一个id作为主键,

    其中@Excelgnore表示导出的时候忽略该字段。

    @Data
    @AllArgsConstructor
    @NoArgsConstructor //如果加上面一个注解,这个必须加上,否则easy excel会报无法实例化
    public class Student {
    
        @TableId(type = IdType.AUTO)
        @ExcelIgnore
        private Integer id;
    
        @ExcelProperty("姓名")
        private String name;
    
        @ExcelProperty("年龄")
        private Integer age;
    
        @ExcelProperty("爱好")
        private String hobby;
    
        @ExcelProperty("分数")
        private Float score;
    
        @ExcelProperty("生日")
        private Date birth;
    }

    DAO

    @Mapper
    public interface StudentMapper extends BaseMapper<Student> {
    }

    service

    @Service
    public class StudentServiceImpl implements StudentService {
    
        @Autowired
        StudentMapper studentMapper;
    
        @Override
        public void insertStudent(Student student) {
            studentMapper.insert(student);
        }
    
        @Override
        public void insertStudents(List<Student> students) {
            students.forEach(student -> studentMapper.insert(student));
        }
    
        @Override
        public List<Student> selectStudents() {
            return studentMapper.selectList(null);
        }
    }
    public interface StudentService {
        void insertStudent(Student student);
    
        void insertStudents(List<Student>students);
    
        List<Student> selectStudents();
    }

    excel

    excel相关的类我也写成了service,便于拓展和使用

    public interface ExcelService {
        void simpleDownload(HttpServletResponse response) throws IOException;
    
        void simpleUpload(MultipartFile file) throws IOException;
    }
    @Service
    public class ExcelServiceImpl implements ExcelService {
        @Autowired
        StudentServiceImpl studentService;
    
        @Autowired
        StudentDataListener studentDataListener;
    
        @Override
        public void simpleDownload(HttpServletResponse response) throws IOException {
            // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), Student.class).sheet("学生信息").doWrite(studentService.selectStudents());
        }
    
        @Override
        public void simpleUpload(MultipartFile file) throws IOException {
            EasyExcel.read(file.getInputStream(), Student.class, studentDataListener).sheet().doRead();
        }
    }
    @Component
    public class StudentDataListener extends AnalysisEventListener<Student> {
    
    
        //因为相关的类没有交给spring管理,所以不能直接通过注解注入
        @Autowired
       private StudentService studentService;
    
    
        //解析每条数据的时候会调用这个方法
        @Override
        public void invoke(Student student, AnalysisContext analysisContext) {
            studentService.insertStudent(student);
        }
    
        //解析完成后调用这个方法
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }

    controller

    @RestController
    public class ExcelController {
        @Autowired
        ExcelService excelService;
    
        //导出
        @GetMapping("/download")
        public void download(HttpServletResponse response) throws IOException {
            excelService.simpleDownload(response);
        }
    
        //导入
        @PostMapping("/upload")
        public String upload(MultipartFile file) throws IOException {
            excelService.simpleUpload(file);
            return "success";
        }
    }

    目录结构

     分析

    1、对比

    web版的excel导入导出,与之前简单demo相比,不需要指定文件的存放路径。

    导入的时候,web端直接分析流文件,将每一行都插进数据库。

    导出的时候,web端将查到数据,直接写入response,无需在服务器端生成临时文件。

    2、问题

    一个项目里会有很多个导入导出,并不只是Student类的导出。

    但是不管是何种数据的导出,api都是相同的,区别就在于handler类不一样(因为我觉得与netty中的handler很像,故如此取名)。

    例如我们现在需要导出学校信息,我们可以这么做:

    第二版

    新增一个实体类;

    @Data
    public class School {
    
        @TableId(type = IdType.AUTO)
        private Integer id;
    
        private String name;
    
        private Student year;
    }

    写好对应的service:

    @Service
    public class SchoolServiceImpl implements SchoolService {
    
        @Autowired
        SchoolMapper schoolMapper;
    
        @Override
        public void insert(School school) {
            schoolMapper.insert(school);
        }
    }

    新增对应的处理类

    @Component
    public class SchoolHandler extends AnalysisEventListener<School> {//因为相关的类没有交给spring管理,所以不能直接通过注解注入
        @Autowired
        private SchoolService schoolService;
    
    
        //解析每条数据的时候会调用这个方法
        @Override
        public void invoke(School school, AnalysisContext analysisContext) {
            schoolService.insert(school);
        }
    
        //解析完成后调用这个方法
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }

    修改excel相关类,将接口设计成可以动态添加 Listen 类

    public interface ExcelService {
        void simpleDownload(HttpServletResponse response) throws IOException;
    
        void simpleUpload(MultipartFile file, AnalysisEventListener listener) throws IOException;
    }
    @Service
    public class ExcelServiceImpl implements ExcelService {
        @Autowired
        StudentServiceImpl studentService;
    
        @Autowired
        StudentDataListener studentDataListener;
    
        @Override
        public void simpleDownload(HttpServletResponse response) throws IOException {
            // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), Student.class).sheet("学生信息").doWrite(studentService.selectStudents());
        }
    
        @Override
        public void simpleUpload(MultipartFile file, AnalysisEventListener listener) throws IOException {
            EasyExcel.read(file.getInputStream(), Student.class, listener).sheet().doRead();
        }
    }

    controller层调用

    @RestController
    public class ExcelController {
        @Autowired
        ExcelService excelService;
    
        @Autowired
        SchoolHandler schoolHandler;
    
        @Autowired
        StudentDataListener studentDataListener;
    
        //导出
        @GetMapping("/download")
        public void download(HttpServletResponse response) throws IOException {
            excelService.simpleDownload(response);
        }
    
        //导入
        @PostMapping("/student/upload")
        public String upload(MultipartFile file) throws IOException {
            excelService.simpleUpload(file, studentDataListener);
            return "success";
        }
    
        @PostMapping("/school/upload")
        public String upload2(MultipartFile file) throws IOException {
            excelService.simpleUpload(file, schoolHandler);
            return "success";
        }
    
    
    }

    其他代码不变。

    补充

    大体框架基本拉出来了,我们需要考虑一下细节问题。

    导出所有sheet

    ExcelService添加一个类

    注意是doReadAll()

        @Override
        public void allSheetUpload(MultipartFile file, AnalysisEventListener listener) throws IOException {
            EasyExcel.read(file.getInputStream(), Student.class, listener).doReadAll();
        }

    导出部分sheet

    这里写死了只有两个sheet。

    一般用户使用的模板都是系统提供的,所以当每个sheet存放不同类型的内容时,我们可以提前感知,在后台进行相应的映射。

    @Override
        public void PartSheetUpload(MultipartFile file, List<AnalysisEventListener>listeners) {
            // 读取部分sheet
    
            ExcelReader excelReader = null;
            try {
                excelReader = EasyExcel.read(file.getInputStream()).build();
    
                // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
                ReadSheet readSheet1 =
                        EasyExcel.readSheet(0).head(Student.class).registerReadListener(listeners.get(0)).build();
                ReadSheet readSheet2 =
                        EasyExcel.readSheet(1).head(School.class).registerReadListener(listeners.get(1)).build();
                // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
                excelReader.read(readSheet1, readSheet2);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (excelReader != null) {
                    // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
                    excelReader.finish();
                }
            }
        }

     格式转换

    可以在对象上直接加注解,也可以自己写一个转化类。

    @Data
    @AllArgsConstructor
    @NoArgsConstructor //如果加上面一个注解,这个必须加上,否则easy excel会报无法实例化
    //@ColumnWidth(25)设置行高
    public class Student {
    
        @TableId(type = IdType.AUTO)
        @ExcelIgnore
        private Integer id;
    
        @ExcelProperty("姓名")
    //    @ColumnWidth(50)设置行高,覆盖上面的设置
        private String name;
    
        @ExcelProperty("年龄")
        private Integer age;
    
        @ExcelProperty("爱好")
        private String hobby;
    
        @ExcelProperty("分数")
        private Float score;
    
        @ExcelProperty("生日")
        @DateTimeFormat("yyyy年MM月dd日")
        private Date birth;
    }

    如果业务比较复杂,需要自己创建转换器

    public class CustomStringStringConverter implements Converter<String> {
        @Override
        public Class supportJavaTypeKey() {
            return null;
        }
    
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return null;
        }
    
        @Override
        public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            return null;
        }
    
        @Override
        public CellData convertToExcelData(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            return null;
        }
    }

    上面根据自己的业务进行填写

    比如要转化成LocalDateTime,就把String替换成 LocalDateTime

    可以参考:https://blog.csdn.net/weixin_47098539/article/details/109385543?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-2-109385543.nonecase&utm_term=easyexcel%20%E6%97%B6%E9%97%B4%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2&spm=1000.2123.3001.4430

    添加转换器

        @Override
        public void Convert(MultipartFile file) throws IOException {
    
            // 这里 需要指定读用哪个class去读,然后读取第一个sheet
            EasyExcel.read(file.getInputStream(), Student.class, studentDataListener)
                    // 这里注意 我们也可以registerConverter来指定自定义转换器, 但是这个转换变成全局了, 所有java为string,excel为string的都会用这个转换器。
                    // 如果就想单个字段使用请使用@ExcelProperty 指定converter
                     .registerConverter(new CustomStringStringConverter())
                    // 读取sheet
                    .sheet().doRead();
        }

    如果工作中用到了其他功能,后面再来补充。 

     异常处理

    消息转换

    控制台报的一个warning,虽然不影响结果,但是看着很烦。

    SpringMvc默认的消息转换 MessageConverters不支持我们设置的媒体类型。添加一个配置类即可解决问题。

    这里用的是默认的jackson,也可以用Gson或者fastjson

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowedMethods("*")
                    .allowCredentials(true)
                    .maxAge(30*1000);
        }

    @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(getSupportedMediaTypes()); converters.add(converter); } public List<MediaType> getSupportedMediaTypes() { //创建fastJson消息转换器 List<MediaType> supportedMediaTypes = new ArrayList<>(); supportedMediaTypes.add(MediaType.APPLICATION_JSON); supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); supportedMediaTypes.add(MediaType.APPLICATION_PDF); supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); supportedMediaTypes.add(MediaType.APPLICATION_XML); supportedMediaTypes.add(MediaType.IMAGE_GIF); supportedMediaTypes.add(MediaType.IMAGE_JPEG); supportedMediaTypes.add(MediaType.IMAGE_PNG); supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); supportedMediaTypes.add(MediaType.TEXT_HTML); supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); supportedMediaTypes.add(MediaType.TEXT_PLAIN); supportedMediaTypes.add(MediaType.TEXT_XML); supportedMediaTypes.add(MediaType.ALL); return supportedMediaTypes; } }

    如有错误,欢迎批评指正~

  • 相关阅读:
    Nginx 解决WebApi跨域二次请求以及Vue单页面问题
    微信小程序部署问题总结
    Webapi文档描述-swagger优化
    [AOP系列]Autofac+Castle实现AOP日志
    WebApi Ajax 跨域请求解决方法(CORS实现)
    MSDTC启用——分布式事务
    [钉钉通知系列]Jenkins发布后自动通知
    [AOP系列]Autofac+Castle实现AOP事务
    [钉钉通知系列]SVN提交后自动推送消息到钉钉群
    Vue H5 History 部署IIS上404问题
  • 原文地址:https://www.cnblogs.com/phdeblog/p/13960693.html
Copyright © 2011-2022 走看看