GVKun编程网logo

如何为返回PDF文件的Spring Boot测试用例设置内容类型(springboot返回pdf文件流)

18

本文将带您了解关于如何为返回PDF文件的SpringBoot测试用例设置内容类型的新内容,同时我们还将为您解释springboot返回pdf文件流的相关知识,另外,我们还将为您提供关于JavaSpri

本文将带您了解关于如何为返回PDF文件的Spring Boot测试用例设置内容类型的新内容,同时我们还将为您解释springboot返回pdf文件流的相关知识,另外,我们还将为您提供关于Java Spring Framework-如何设置内容类型?、spring boot itextPdf根据模板生成pdf文件、Spring Boot PDF文件转图片、spring boot 测试用例的实用信息。

本文目录一览:

如何为返回PDF文件的Spring Boot测试用例设置内容类型(springboot返回pdf文件流)

如何为返回PDF文件的Spring Boot测试用例设置内容类型(springboot返回pdf文件流)

我目前正在使用Spring boot test测试我的一项服务,该服务导出所有用户数据并在成功完成后生成CSV或PDF。在浏览器中下载文件。

以下是我在测试课程中编写的代码

MvcResult result =   MockMvc.perform(post("/api/user-accounts/export").param("query","id==''123''")    .contentType(MediaType.APPLICATION_JSON_VALUE)    .accept(MediaType.APPLICATION_PDF_VALUE)    .content(TestUtil.convertObjectToJsonBytes(userObjectDTO)))    .andExpect(status().isOk())    .andExpect(content().contentType(MediaType.APPLICATION_PDF_VALUE))    .andReturn();String content = result.getResponse().getContentAsString();  // verify the response string.

以下是我的资源类代码(致电此地点)-

    @PostMapping("/user-accounts/export")@Timedpublic ResponseEntity<byte[]> exportAllUsers(@RequestParam Optional<String> query, @ApiParam Pageable pageable, @RequestBody UserObjectDTO userObjectDTO) {HttpHeaders headers = new HttpHeaders();... return new ResponseEntity<>(outputContents, headers, HttpStatus.OK); }

当我调试服务并将调试放在出口之前时,我得到的内容类型为“ application /
pdf”,状态为200。我试图在测试用例中复制相同的内容类型。在执行过程中总以某种方式使其低于错误-

   java.lang.AssertionError: Status    Expected :200   Actual   :406

我想知道,我应该如何检查我的响应(ResponseEntity)。同样,响应所需的内容类型应该是什么。

答案1

小编典典

我在@veeram的帮助下找到了答案,并了解到我的配置MappingJackson2HttpMessageConverter缺少我的要求。我覆盖了默认设置Mediatype,它解决了该问题。

默认支持-

implication/jsonapplication*/json

完成代码更改以解决这种情况-

@Autowiredprivate MappingJackson2HttpMessageConverter jacksonMessageConverter;List<MediaType> mediaTypes = new ArrayList<>();mediaTypes.add(MediaType.ALL);jacksonMessageConverter.setSupportedMediaTypes(mediaTypes);

Java Spring Framework-如何设置内容类型?

Java Spring Framework-如何设置内容类型?

我有一个弹簧动作,我正在从控制器渲染一些json,在它返回内容类型为’text / plain; charset = ISO-8859-1’的那一刻。

如何将其更改为“ application / json”?

spring boot itextPdf根据模板生成pdf文件

spring boot itextPdf根据模板生成pdf文件

在开发一些平台中会遇到将数据库中的数据渲染到PDF模板文件中的场景,用itextPdf完全动态生成PDF文件的太过复杂,通过itextPdf/AcroFields可以比较简单的完成PDF数据渲染工作(PDF模板的表单域数据需定义名称)

  • Controller获取HttpServletResponse 输出流
package pdf.controller;

import com.itextpdf.text.DocumentException;
import service.PdfService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(WebConstants.WEB_pdf + "/download")
@Api(description = "pdf下载相关", tags = "Pdf.download")
@NoAuth
public class PdfDownloadController {

    @Autowired
    private PdfService PdfService;
    
    @Value("${pdf.template.path}")
    private String templatePath ;

    @ApiOperation(value = "申请表下载")
    @RequestMapping(value = "/download/{id}", method = RequestMethod.GET)
    @ResponseBody 
    @NoLogin
    public void download(@PathVariable("id") Long id, HttpServletResponse response) throws IOException, DocumentException {
        
        //设置响应contenType
        response.setContentType("application/pdf");
        //设置响应文件名称
        String fileName = new String("申请表.pdf".getBytes("UTF-8"),"iso-8859-1");
        //设置文件名称
        response.setHeader("Content-Disposition", "attachment; filename="+fileName);
        //获取输出流
        OutputStream out = response.getOutputStream(); 
        PdfService.download(id, templatePath ,out);
    }
}
  • Service生成pdf数据响应输出流
1.业务service-负责实现获取pfd模板数据,数据库数据,实现动态赋值生成PDF

package service.impl;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

@Service
public class ApplyServiceImpl implements ApplyService {

    @Override
    public DetailDTO getDetail(Long id) {
       // 获取业务数据
       return null;
    }
    
    @Override
    public Map<String, String> getPdfMapping(DetailDTO dto) {
        // TODO Auto-generated method stub
        // 获取pdf与数据库的数据字段映射map
    }
    
    @Override
    public void download(Long id, String templatePath, OutputStream out) {
        // TODO Auto-generated method stub
        DetailDTO dto  =  getDetail(id);
        Map<String, String> fieldMapping = getPdfMapping(dto);
        String filePath;
        byte[] pdfTemplate;
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
        try {
            //获取模板文件路径
            filePath = ResourceUtils.getURL(templatePath).getPath();
            //获取模板文件字节数据
            pdfTemplate = IOUtils.toByteArray(new FileInputStream(filePath));
            //获取渲染数据后pdf字节数组数据
            byte[] pdfByteArray = generatePdfByTemplate(pdfTemplate, fieldMapping);
            pdfOutputStream.write(pdfByteArray);
            pdfOutputStream.writeTo(out);
            pdfOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                pdfOutputStream.close();
                out.flush();  
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  
        }

    }

    @Override
    //itextPdf/AcroFields完成PDF数据渲染
    public byte[] generatePdfByTemplate(byte[] pdfTemplate, Map<String, String> pdfParamMapping) {
        Assert.notNull(pdfTemplate, "template is null");
        if (pdfParamMapping == null || pdfParamMapping.isEmpty()) {
            throw new IllegalArgumentException("pdfParamMapping can''t be empty");
        }

        PdfReader pdfReader = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfStamper stamper = null;
        try {
            // 读取pdf模板
            pdfReader = new PdfReader(pdfTemplate);
            stamper = new PdfStamper(pdfReader, baos);
            //获取所有表单字段数据
            AcroFields form = stamper.getAcroFields();
            form.setGenerateAppearances(true);

            // 设置
            ArrayList<BaseFont> fontList = new ArrayList<>();
            fontList.add(getMsyhBaseFont());
            form.setSubstitutionFonts(fontList);

            // 填充form
            for (String formKey : form.getFields().keySet()) {
                form.setField(formKey, pdfParamMapping.getOrDefault(formKey, StringUtils.EMPTY));
            }
            // 如果为false那么生成的PDF文件还能编辑,一定要设为true
            stamper.setFormFlattening(true);
            stamper.close();
            return baos.toByteArray();
        } catch (DocumentException | IOException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            if (stamper != null) {
                try {
                    stamper.close();
                } catch (DocumentException | IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
            if (pdfReader != null) {
                pdfReader.close();
            }

        }
        throw new SystemException("pdf generate failed");
    }

    /**
     * 默认字体
     *
     * @return
     */
    private BaseFont getDefaultBaseFont() throws IOException, DocumentException {
        return BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    }

    /**
     * 微软宋体字体
     *
     * @return
     */
     //设定字体
    private BaseFont getMsyhBaseFont() throws IOException, DocumentException {
        try {
            return BaseFont.createFont("/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (DocumentException | IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return getDefaultBaseFont();
    }
}
  • 数据库的数据到pdf字段的映射可以使用配置,建立数据字段映射表,通过反射
    可以将数据库数 据对象转为map,再通过定义的静态map映射表,将数据map转
    换为pdf表单数据map
    BeanUtils.bean2Map(bean);
    /**
     * JavaBean对象转化成Map对象
     * @param javaBean
     * @return
     */
    public static Map bean2Map(Object javaBean) {
        Map map = new HashMap();

        try {
            // 获取javaBean属性
            BeanInfo beanInfo = Introspector.getBeanInfo(javaBean.getClass());

            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            if (propertyDescriptors != null && propertyDescriptors.length > 0) {
                String propertyName = null; // javaBean属性名
                Object propertyValue = null; // javaBean属性值
                for (PropertyDescriptor pd : propertyDescriptors) {
                    propertyName = pd.getName();
                    if (!propertyName.equals("class")) {
                        Method readMethod = pd.getReadMethod();
                        propertyValue = readMethod.invoke(javaBean, new Object[0]);
                        map.put(propertyName, propertyValue);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
    
    字段映射配置
    public class PdfMapping {

        public final static Map<String, String> BASE_INFO_MAPPING = new HashMap() {
           {
            put("name", "partyA");
            put("identity", "baseIdentity");

           }
        };
    }

Spring Boot PDF文件转图片

Spring Boot PDF文件转图片

spring boot 里的 pdf 转 图片

开发环境:

  • java 8

  • spring boot 2.x

  • 前后端分离

需求:先从FTP文件服务器里获取PDF文件,再把PDF文件转换成图片。

废话不多说,直接开干

1、导出PDF转图片的依赖

        <dependency>
            <groupId>org.apache.pdfBox</groupId>
            <artifactId>pdfBox</artifactId>
            <version>2.0.16</version>
        </dependency>

2、编写Controller

    /**
     * 读取ftp上的pdf文件 并转成图片
     * @param resp
     * @param path
     * @throws Exception
     */
    @PostMapping("/readPdfFileImg")
    public void readPdfFileImg(HttpServletResponse resp, String path) throws Exception {
        // 获取ftp的文件字节流
        InputStream is = ftputils.readFileIs(path);
        // pdf转图片
        PDDocument doc = PDDocument.load(is);
        PDFRenderer renderer = new PDFRenderer(doc);
        int pageCount = doc.getNumberOfPages();
        for (int i = 0; i < pageCount; i++) {
            // dpi,图片像素点,dpi越高图片体积越大,216很清晰,105体积稳定
            BufferedImage image = renderer.renderImageWithDPI(i, 216);
            // 格式为JPG
            ImageIO.write(image, "jpg", resp.getoutputStream());
        }
        String filename = path.substring(path.lastIndexOf("/")+1).replaceAll(".pdf",".jpg");
        resp.setContentType("image/jpeg;charset=UTF-8");
        resp.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
    }

3、通过PostMan测试

ok

spring boot 测试用例

spring boot 测试用例

 junit 是一个面向于研发人员使用的轻量的测试模块,适合做单元测试。而testng百度后发现更强大,可以做功能测试,但对于我这种RD,貌似junit足沟了呢!

java Mock PowerMock、jmockit 模拟包非常优秀,我目前选型学会一个就不错了,不做评价,我学的powermock,据说jmockit更强大。但是powermock貌似继承了旧的easymock和jmock,所以用的人比较大(个人理解)。

 

对于junit测试的几个注解

@RunWith

@Before 

@Test

@After

 

powerMock注解

@Mock

@InjectMocks

 

@RunWith 表示运行方式,@RunWith(JUnit4TestRunner)、@RunWith(SpringRunner.class),@RunWith(PowerMockRunner.class) 三种运行方式,分别在不同的场景中使用。

@Before是 @Test运行之前调用的方法,可以做初始化操作

@Test  是测试用例的单元

@After 执行完测试用例需要执行的清理工作

@Mock  有点类似Autowired注解,而@Mock注解是自动实现模拟对象,而并非Bean实例创建

@InjectMocks 实现对@Mock注解的对象注入到当前对象中,通过MockitoAnnotations.initMocks(this);实现

 

package aa;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.mockito.Matchers.any;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@RunWith(PowerMockRunner.class)
@SpringBootTest(classes = MainApplication.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@PowerMockIgnore("javax.management.*") 
public class moreTest {

    @Mock
    TService tService;
    @InjectMocks
    TController controller;
    @Autowired
    private WebApplicationContext ctx;
    private MockMvc mvc;

    @Before
    public void before() throws Exception {

        MockitoAnnotations.initMocks(this);
//如果简单mock一个请求可以使用这个,但是要模拟注入,还是按下面的方式实现controller比较好
//        mvc = MockMvcBuilders.webAppContextSetup(ctx).build();
        mvc = MockMvcBuilders.standaloneSetup(controller).build();
//        taskPackageService=PowerMockito.mock(TService);
        PowerMockito.when(tService.queryMethod(any(ParameClass.class)))
                .thenReturn(88);
    PowerMockito.whenNew(TService.class).withNoArguments().thenReturn(tService);
    }

    @Test
    public void searchTest() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/welcome").header("User-Agent", "xx")
                .param("page", "1")
        ).andExpect(status().isOk()).andDo((MvcResult result) -> {
            System.out.println(result.getResponse().getContentAsString());
        });
    }

}

 

关于如何为返回PDF文件的Spring Boot测试用例设置内容类型springboot返回pdf文件流的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Java Spring Framework-如何设置内容类型?、spring boot itextPdf根据模板生成pdf文件、Spring Boot PDF文件转图片、spring boot 测试用例等相关知识的信息别忘了在本站进行查找喔。

本文标签: