¿Cómo el código de combate real de springboot devuelve imágenes con gracia?

Código de combate real de Springboot: [Cómo devolver imágenes con gracia]

Este artículo resumirá los métodos comunes para devolver imágenes:

  1. Retorno de transmisión: principalmente porque la implementación es diferente, en función de la respuesta y HttpConvertMessage
  2. devuelve base64

Explicación

La imagen puede provenir de muchos lugares, puede ser una carpeta local, también puede ser una secuencia de red o un binario de base de datos, aquí, por simplicidad, se utilizan archivos locales.

@RestController
@RequestMapping("/")
public class ImgController {

    private String imgPath = "E:\\meme.png";

    private InputStream getImgInputStream() throws FileNotFoundException {
        return new FileInputStream(new File(imgPath));
    }

Depende de

Los IOUtils que se usan a continuación deberían ser familiares para todos, desde el clásico módulo common-io

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

1. Retorno basado en la respuesta

De manera muy básica y simple:

import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;

    /**
     * 使用response输出图片流
     */
    @GetMapping("/img-response")
    public void getImage(HttpServletResponse resp) throws IOException {
        final InputStream in = getImgInputStream();
        resp.setContentType(MediaType.IMAGE_PNG_VALUE);
        IOUtils.copy(in, resp.getOutputStream());
    }

2. Devuelve el flujo de bytes basado en productores

2.1 Devolución de flujo de bytes sin formato

Primero veamos qué sucede si la secuencia de bytes devuelve directamente la imagen:

    /**
     * 试试直接返回字节流,不指定content-type
     */
    @GetMapping(value = "/img-byte")
    public byte[] getImageByte() throws IOException {
        final InputStream in = getImgInputStream();
        return IOUtils.toByteArray(in);
    }

El resultado es el siguiente: ilegible, porque el tipo de contenido es incorrecto
img-response ilegible

2.2 Especifique el tipo de contenido para devolver la secuencia de bytes

Use productores para especificar tipos: aquí especificamos 2 tipos y vemos qué sucede

    @GetMapping(value = "/img-media-type",
            produces = {MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
    public byte[] getImage() throws IOException {
        final InputStream in = getImgInputStream();
        return IOUtils.toByteArray(in);
    }

La imagen se puede devolver normalmente, pero una mirada más cercana, la razón en el encabezado de respuesta content-typees image/jpeg
img jpeg
que cuando solicitamos por defecto, springboot coincide con el primer tipo de jpeg, aunque somos una imagen png.

Entonces, ¿cómo hacemos que devuelva el tipo de contenido image/png?
Al leer los comentarios del código fuente, sabemos que
produce
solo necesitamos pasar el lugar que queremos cuando se lo solicite Accept. El siguiente es un ejemplo de cartero:
imagen png

De hecho, este método también se puede usar en la /img-byteinterfaz anterior y no devolverá caracteres ilegibles.
byte img
Al mismo tiempo, si pasamos un tipo no admitido, obtendremos 406un error:
406

2.3 Descargar archivos de imagen directamente

Si queremos abrir directamente el cuadro de descarga, podemos especificar el tipo de contenido como:application/octet-stream

    @GetMapping(value = "/img-file.png", 
    	produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    public byte[] getImageFile() throws IOException {
        final InputStream in = getImgInputStream();
        return IOUtils.toByteArray(in);
    }

xiazai

    @GetMapping(value = "/img/{iconId}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE})
    public byte[] getImage(@PathVariable String iconId) throws IOException {
        final GisIcon icon = iconService.getById(iconId);
        if (icon == null) {
            throw new IllegalArgumentException("不存在此图片");
        }
        final FileInputStream fio = new FileInputStream(new File(iconService.getSavePath(icon.getUsername(),
                icon.getName(), icon.getId())));
        byte[] bytes = new byte[fio.available()];
        log.info("读取文件结果:{}", fio.read(bytes, 0, fio.available()));
        return bytes;
    }

3. imagen base64

import java.util.Base64;

    @GetMapping("/img-base64")
    public String getBase64Img() throws IOException {
        final byte[] bytes = IOUtils.toByteArray(getImgInputStream());
        return Base64.getEncoder().encodeToString(bytes);
    }

Recepción frontal:

function reqListener (base64) {
  var body = document.getElementsByTagName("body");
  var img = document.createElement("img");
  img.src = "data:image/png;base64, "+base64;
  body.appendChild(img);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://localhost:8013/img-base64");
oReq.send();
80 artículos originales publicados · Me gusta 319 · Visitas 340,000+

Supongo que te gusta

Origin blog.csdn.net/jimo_lonely/article/details/105305522
Recomendado
Clasificación