The image data is directly returned in the springBoot interface


Recently, I am doing a business involving sharing and promotion, and the salesperson needs to share the QR code to enter the promotion page. Since it is a new project, the initial budget and usage are limited, and there is no [object storage] service, so I decided to use the background service to dynamically generate the QR code. Picture directly picture data and return.

The first is the generation of the QR code. I decided to use google’s zxing. After all, Google’s things are still good. [Maven] adds dependencies as follows:

<!-- -->
        <!-- -->

Continuing to check the use of zxing, I found that most of them are generated QR codes and then written as picture files, which is not suitable for my current situation. similar to this

Map hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);
        BitMatrix qrcode = new QRCodeWriter().encode(href, BarcodeFormat.QR_CODE, 300 , 300 );
         //Most online solutions are written to the file system through io streams, 
        MatrixToImageWriter.writeToStream(qrcode, "png" ,response. getOutputStream());

So I tried to use the output stream of the response to return, but the returned data browser saw all garbled characters, this solution was not successful

However, according to personal experience, since the QR code data BitMatrix objects are generated in this open source solution, there must be a way to obtain the original data. Click on the MatrixToImageWriter class search method, and sure enough, I found a method that can directly return the BufferedImage object.

Now, the BufferedImage object already exists, just throw it back to the front end, continue to Baidu, and find that the object can be returned directly, similar to the following configuration

@GetMapping(value = "/qrcode", produces = MediaType.IMAGE_JPEG_VALUE)
public BufferedImage generateQRCode() {

I thought the problem was about to be solved, but the browser access returned 406, and I checked the Internet. It turned out that there was no converter corresponding to the message type. Some bloggers mentioned that the following configuration is required

    public BufferedImageHttpMessageConverter addConverter(){
        return new BufferedImageHttpMessageConverter();

After adding the above configuration, I found that the problem has not been solved, and the error is still 406. I suspected that the configuration did not take effect, so I decided to go to the source code to check the reason. When debugging the source code, I found that there is really no configuration in the list of messageConverters, indicating that it is indeed a configuration problem. Find the set operation of messageConverters and find the place as shown in the figure.

It is found that springMVC is configuring the HttpMessageConverter set by RequestMappingHandlerAdapter, and enters the getMessageConverters() method.
According to my site English level 8, the extendMessageConverters method should be adding a custom HttpMessageConverter, and entering this method is
empty. Obviously, it is estimated that it is a template mode, and you need to do it yourself. To extend, so I wrote a configuration class to inherit WebMvcConfigurationSupport, rewrite the extendMessageConverters method

    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new BufferedImageHttpMessageConverter());

Browser re-visit, QR code picture display, problem solving


In the process of implementing a solution, I encountered all kinds of strange problems. The best way is to find information on the Internet to quickly solve the problem. If it cannot be solved, then go to the source code to find the root cause of the problem. The most complicated part of solving the problem is positioning the problem. Once the problem is positioned, the solution is no longer a problem.

Leave a Comment

Your email address will not be published. Required fields are marked *