SpringBoot中文件上传与下载&swagger的使用

SpringBoot中文件上传与下载&swagger的使用

一、文件上传

单元测试:

//模拟上传文件
@Test
public void whenUploadSuccess() throws Exception {
    String result = mockMvc.perform(fileUpload("/file")
            .file(new MockMultipartFile("file","test.txt","multipart/form-data","hello upload".getBytes("UTF-8"))))
            .andExpect(status().isOk())
            .andReturn().getResponse().getContentAsString();
    System.out.println(result);
    //{"path":"D:\\WorkSpaces\\stsWS\\hcx-security-demo\\src\\main\\java\\com\\hcx\\web\\controller\\1524895173355.txt"}
}

Controller:

@RestController
@RequestMapping("/file")
public class FileController {
    
    @PostMapping
    public FileInfo upload(MultipartFile file) throws Exception{
        
        System.out.println(file.getName());//file
        System.out.println(file.getOriginalFilename());//test.txt
        System.out.println(file.getSize());//12
        String folder = "D:\\WorkSpaces\\stsWS\\hcx-security-demo\\src\\main\\java\\com\\hcx\\web\\controller";
        File localFile = new File(folder,new Date().getTime()+".txt");
        file.transferTo(localFile);
        return new FileInfo(localFile.getAbsolutePath());
    }
}
SpringBoot中文件上传与下载&swagger的使用_第1张图片
生成的文件及其内容.png

二、文件下载

package com.hcx.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.hcx.web.dto.FileInfo;

@RestController
@RequestMapping("/file")
public class FileController {
    
    private String folder = "D:\\\\WorkSpaces\\\\stsWS\\\\hcx-security-demo\\\\src\\\\main\\\\java\\\\com\\\\hcx\\\\web\\\\controller";
    
    @PostMapping
    public FileInfo upload(MultipartFile file) throws Exception{
        
        System.out.println(file.getName());//file
        System.out.println(file.getOriginalFilename());//test.txt
        System.out.println(file.getSize());//12
        String folder = "D:\\WorkSpaces\\stsWS\\hcx-security-demo\\src\\main\\java\\com\\hcx\\web\\controller";
        File localFile = new File(folder,new Date().getTime()+".txt");
        file.transferTo(localFile);
        return new FileInfo(localFile.getAbsolutePath());
        
    }
    
    @GetMapping("/{id}")
    public void download(@PathVariable String id,HttpServletRequest request,HttpServletResponse response) throws Exception{
        try(
        InputStream inputStream = new FileInputStream(new File(folder,id+".txt"));
        OutputStream outputStream = response.getOutputStream();){
            response.setContentType("application/x-download");
            response.addHeader("Content-Disposition", "attachment;filename=test.txt");
            
            IOUtils.copy(inputStream, outputStream);
            outputStream.flush();
        }
    }

}

启动项目,在浏览器中访问:localhost:8060/file/1524895173355

三、与前端并行工作

1.使用swagger自动生成html文档

通过该文档可以把写的RESTfulAPI向前端描述清楚
根据代码自动生成文档;
改过代码之后,也可以自动更新文档,而不用手动再去修改文档

第一步:添加依赖:

Springfox Swagger2:扫描文件,生成文档数据


    io.springfox
    springfox-swagger2
    2.7.0

Springfox Swagger UI:生成最终看到的可视化界面


    io.springfox
    springfox-swagger-ui
    2.7.0

第二步:在DemoApplication启动类中添加注解:@EnableSwagger2

@SpringBootApplication
@RestController
@EnableSwagger2
public class DemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    
    @GetMapping("/hello")
    public String hello() {
        return "hello spring security";
    }

}

启动项目,访问localhost:8060/swagger-ui.html
页面列出了系统所有的Controller和endpoint

SpringBoot中文件上传与下载&swagger的使用_第2张图片
swagger-ui.png
SpringBoot中文件上传与下载&swagger的使用_第3张图片
swagger接口示例.png
SpringBoot中文件上传与下载&swagger的使用_第4张图片
swagger接口示例.png

点击try it out真正分发出请求:

SpringBoot中文件上传与下载&swagger的使用_第5张图片
tryitout.png

但是对于每个字段,文档中并没能给出具体的含义,可以通过注解来达到此要求:

①描述方法:@ApiOperation(value="用户查询服务")

该value会默认替换成方法名

②参数描述:

第一种情况:当参数为一个对象时:在对象相应的属性上添加注解@ApiModelProperty(value=""):

public class UserQueryCondition {
    private String username;
    @ApiModelProperty(value="用户年龄起始值")
    private int age;
    @ApiModelProperty(value="用户年龄终止值")
    private int ageTo;
    
    private String weight;
}

第二种情况:参数直接是基本数据类型,没有封装对象,使用@ApiParam(""):

@GetMapping("/{id:\\d+}")
@JsonView(User.UserDetailView.class)
public User getInfo(@ApiParam("用户id") @PathVariable String id) {
    //throw new UserNotExistException(id);
    System.out.println("进入getInfo服务");
    User user = new User();
    user.setUsername("tom");
    return user;
}
SpringBoot中文件上传与下载&swagger的使用_第6张图片
通过使用注解描述方法和参数.png

2.使用WireMock快速伪造RESTful服务

WireMock实际上是一个独立的服务器,通过他的客户端写一些代码来编辑该服务器,告诉服务器收到什么请求返回什么响应;可以随时通过客户端代码和api改变服务器的行为,服务器一直运行,不需要重启,不需要反复部署。

SpringBoot中文件上传与下载&swagger的使用_第7张图片
使用wiremock服务器.png

①下载wiremock:http://wiremock.org/docs/running-standalone/

SpringBoot中文件上传与下载&swagger的使用_第8张图片
下载wiremock.png

②启动wiremock:使用命令$ java -jar wiremock-standalone-2.17.0.jar

注:在Windows上是不需要$这个的,直接是java -jar wiremock-standalone-2.17.0.jar

SpringBoot中文件上传与下载&swagger的使用_第9张图片
wiremock启动界面.png

③添加wiremock依赖:


    com.github.tomakehurst
    wiremock
    2.5.1

编写代码:

package com.hcx.web.wiremock;

import com.github.tomakehurst.wiremock.client.WireMock;

//该类是一个客户端,要连接后台启动的服务器
public class MockServer {

    public static void main(String[] args) {
        //告诉服务器,如何处理外界的请求
        //指明服务器的位置
        WireMock.configureFor(8062);//此处在本地,所以不需要再指定ip了
        WireMock.removeAllMappings();//把之前的配置都清空
        
        //伪造一个测试桩
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo("/order/1"))
                .willReturn(WireMock.aResponse().withBody("{\"id\":1}")
                        .withStatus(200)));
        
    }
}

此时访问浏览器localhost:8062/order/1可以得到对应的结果:

{"id":1}

对代码进行重构:

把json单独拿出去:

SpringBoot中文件上传与下载&swagger的使用_第10张图片
把json单独写进一个文件里.png

修改代码:

package com.hcx.web.wiremock;

import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.io.ClassPathResource;

import com.github.tomakehurst.wiremock.client.WireMock;

//该类是一个客户端,要连接后台启动的服务器
public class MockServer {

    public static void main(String[] args) throws Exception{
        //告诉服务器,如何处理外界的请求
        //指明服务器的位置
        WireMock.configureFor(8062);//此处在本地,所以不需要再指定ip了
        WireMock.removeAllMappings();//把之前的配置都清空
        
        mock("/order/1","01");
        //加其服务
        mock("/order/2","02");
        
    }
    
    public static void mock(String url,String file) throws IOException {
        ClassPathResource resource = new ClassPathResource("mock/response/"+file+".txt");
        String content = StringUtils.join(FileUtils.readLines(resource.getFile(),"UTF-8").toArray(),"\n");
//              FileUtils.readFileToString(resource.getFile());
        //伪造一个测试桩
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(url))
                .willReturn(WireMock.aResponse().withBody(content)
                        .withStatus(200)));
    }
}

01.txt:

{
    "id":1,
    "type":"A"

}

你可能感兴趣的:(SpringBoot中文件上传与下载&swagger的使用)