| 
 | 
 
springboot对redis存取二进制数据 
可以用 RedisTemplate 配置成“值为 byte[] 的模板”,用 ByteArrayRedisSerializer 确保按原始二进制读写(不做字符编码/对象序列化)。 配置 - package com.example.config;
 
  
- import org.springframework.context.annotation.Bean;
 
 - import org.springframework.context.annotation.Configuration;
 
 - import org.springframework.data.redis.connection.RedisConnectionFactory;
 
 - import org.springframework.data.redis.core.RedisTemplate;
 
 - import org.springframework.data.redis.serializer.ByteArrayRedisSerializer;
 
 - import org.springframework.data.redis.serializer.StringRedisSerializer;
 
  
- @Configuration
 
 - public class RedisBinaryConfig {
 
  
-     @Bean
 
 -     public RedisTemplate<String, byte[]> binaryRedisTemplate(RedisConnectionFactory cf) {
 
 -         RedisTemplate<String, byte[]> t = new RedisTemplate<>();
 
 -         t.setConnectionFactory(cf);
 
 -         t.setKeySerializer(StringRedisSerializer.UTF_8);
 
 -         t.setValueSerializer(ByteArrayRedisSerializer.INSTANCE);
 
 -         t.setHashKeySerializer(StringRedisSerializer.UTF_8);
 
 -         t.setHashValueSerializer(ByteArrayRedisSerializer.INSTANCE);
 
 -         t.afterPropertiesSet();
 
 -         return t;
 
 -     }
 
 - }
 
  复制代码 
使用 
 
- import org.springframework.data.redis.core.RedisTemplate;
 
 - import org.springframework.beans.factory.annotation.Autowired;
 
 - import java.time.Duration;
 
  
- public class BinService {
 
 -     @Autowired
 
 -     private RedisTemplate<String, byte[]> binaryRedisTemplate;
 
  
-     public void save(String key, byte[] data, Duration ttl) {
 
 -         binaryRedisTemplate.opsForValue().set(key, data, ttl);
 
 -     }
 
  
-     public byte[] get(String key) {
 
 -         return binaryRedisTemplate.opsForValue().get(key);
 
 -     }
 
  
-     public void saveHash(String hkey, String field, byte[] data) {
 
 -         binaryRedisTemplate.opsForHash().put(hkey, field, data);
 
 -     }
 
  
-     public byte[] getHash(String hkey, String field) {
 
 -         Object v = binaryRedisTemplate.opsForHash().get(hkey, field);
 
 -         return v instanceof byte[] ? (byte[]) v : null;
 
 -     }
 
 - }
 
  复制代码 
 
要点 - 不要用 StringRedisTemplate 保存二进制,否则会按 UTF-8 编码导致损坏。
 - Redis 单个 value 最大 512MB;超大文件建议分片或改用对象存储。
 - 若直接用底层连接也可:connection.set(key.getBytes(StandardCharsets.UTF_8), bytes)。
 
 
  
下面给出一个最小可用的服务端与客户端示例,演示通过 HTTP 存/取 Redis 中的二进制数据。 服务端(Spring Boot) - PUT /bin/{key}:请求体即二进制;可选 ttl 秒
 - GET /bin/{key}:返回 application/octet-stream 的二进制
 
 
 - package com.example.web;
 
  
- import org.springframework.http.*;
 
 - import org.springframework.web.bind.annotation.*;
 
 - import org.springframework.beans.factory.annotation.Autowired;
 
 - import org.springframework.data.redis.core.RedisTemplate;
 
  
- import java.time.Duration;
 
 - import java.util.Optional;
 
  
- @RestController
 
 - @RequestMapping("/bin")
 
 - public class BinaryController {
 
  
-     @Autowired
 
 -     private RedisTemplate<String, byte[]> binaryRedisTemplate;
 
  
-     @PutMapping("/{key}")
 
 -     public ResponseEntity<Void> put(@PathVariable String key,
 
 -                                     @RequestBody byte[] body,
 
 -                                     @RequestParam(name = "ttl", required = false) Optional<Long> ttlSec) {
 
 -         if (ttlSec.isPresent()) {
 
 -             binaryRedisTemplate.opsForValue().set(key, body, Duration.ofSeconds(ttlSec.get()));
 
 -         } else {
 
 -             binaryRedisTemplate.opsForValue().set(key, body);
 
 -         }
 
 -         return ResponseEntity.accepted().build();
 
 -     }
 
  
-     @GetMapping("/{key}")
 
 -     public ResponseEntity<byte[]> get(@PathVariable String key) {
 
 -         byte[] data = binaryRedisTemplate.opsForValue().get(key);
 
 -         if (data == null) return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
 
 -         HttpHeaders h = new HttpHeaders();
 
 -         h.setContentType(MediaType.APPLICATION_OCTET_STREAM);
 
 -         h.setContentLength(data.length);
 
 -         // 可选下载文件名:
 
 -         // h.setContentDisposition(ContentDisposition.attachment().filename(key + ".bin").build());
 
 -         return new ResponseEntity<>(data, h, HttpStatus.OK);
 
 -     }
 
 - }
 
  复制代码客户端调用示例 - # 上传二进制,设置 1 小时过期
 
 - curl -X PUT --data-binary @image.png "http://localhost:8080/bin/pic1?ttl=3600"
 
  
- # 下载二进制到文件
 
 - curl -o out.png "http://localhost:8080/bin/pic1"
 
  复制代码- import java.net.http.*;
 
 - import java.net.URI;
 
 - import java.nio.file.*;
 
  
- public class ClientDemo {
 
 -     public static void main(String[] args) throws Exception {
 
 -         HttpClient http = HttpClient.newHttpClient();
 
  
-         // PUT 上传
 
 -         byte[] bytes = Files.readAllBytes(Path.of("image.png"));
 
 -         HttpRequest put = HttpRequest.newBuilder(URI.create("http://localhost:8080/bin/pic1?ttl=3600"))
 
 -                 .PUT(HttpRequest.BodyPublishers.ofByteArray(bytes))
 
 -                 .header("Content-Type", "application/octet-stream")
 
 -                 .build();
 
 -         http.send(put, HttpResponse.BodyHandlers.discarding());
 
  
-         // GET 下载
 
 -         HttpRequest get = HttpRequest.newBuilder(URI.create("http://localhost:8080/bin/pic1")).GET().build();
 
 -         HttpResponse<byte[]> resp = http.send(get, HttpResponse.BodyHandlers.ofByteArray());
 
 -         if (resp.statusCode() == 200) Files.write(Path.of("download.png"), resp.body());
 
 -     }
 
 - }
 
  复制代码说明 - 需配合你前面配置的 RedisTemplate<String, byte[]>(ByteArrayRedisSerializer)使用。
 - value 最大 512MB;大对象建议分片或对象存储。
 
 
  
 
下面给出一个可在 Java 8 (1.8.0_152) 运行的 Spring Boot 2.7 示例:用 RedisTemplate<String, byte[]> 读写二进制,并通过 HTTP 接口让客户端上传/下载。 pom.xml - <project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
 -          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
 -   <modelVersion>4.0.0</modelVersion>
 
 -   <groupId>com.example</groupId>
 
 -   <artifactId>redis-binary-demo</artifactId>
 
 -   <version>1.0.0</version>
 
 -   <parent>
 
 -     <groupId>org.springframework.boot</groupId>
 
 -     <artifactId>spring-boot-starter-parent</artifactId>
 
 -     <version>2.7.18</version>
 
 -   </parent>
 
 -   <properties>
 
 -     <java.version>1.8</java.version>
 
 -   </properties>
 
 -   <dependencies>
 
 -     <dependency>
 
 -       <groupId>org.springframework.boot</groupId>
 
 -       <artifactId>spring-boot-starter-web</artifactId>
 
 -     </dependency>
 
 -     <dependency>
 
 -       <groupId>org.springframework.boot</groupId>
 
 -       <artifactId>spring-boot-starter-data-redis</artifactId>
 
 -     </dependency>
 
 -     <dependency>
 
 -       <groupId>org.apache.commons</groupId>
 
 -       <artifactId>commons-pool2</artifactId>
 
 -     </dependency>
 
 -   </dependencies>
 
 -   <build>
 
 -     <plugins>
 
 -       <plugin>
 
 -         <groupId>org.springframework.boot</groupId>
 
 -         <artifactId>spring-boot-maven-plugin</artifactId>
 
 -       </plugin>
 
 -     </plugins>
 
 -   </build>
 
 - </project>
 
  复制代码 application.yml- spring:
 
 -   redis:
 
 -     host: 127.0.0.1
 
 -     port: 6379
 
 - server:
 
 -   port: 8080
 
  复制代码 配置 RedisTemplate(值为 byte[]) 
- package com.example.config;
 
  
- import org.springframework.context.annotation.Bean;
 
 - import org.springframework.context.annotation.Configuration;
 
 - import org.springframework.data.redis.connection.RedisConnectionFactory;
 
 - import org.springframework.data.redis.core.RedisTemplate;
 
 - import org.springframework.data.redis.serializer.ByteArrayRedisSerializer;
 
 - import org.springframework.data.redis.serializer.StringRedisSerializer;
 
  
- @Configuration
 
 - public class RedisBinaryConfig {
 
 -     @Bean
 
 -     public RedisTemplate<String, byte[]> binaryRedisTemplate(RedisConnectionFactory cf) {
 
 -         RedisTemplate<String, byte[]> t = new RedisTemplate<>();
 
 -         t.setConnectionFactory(cf);
 
 -         t.setKeySerializer(StringRedisSerializer.UTF_8);
 
 -         t.setValueSerializer(ByteArrayRedisSerializer.INSTANCE);
 
 -         t.setHashKeySerializer(StringRedisSerializer.UTF_8);
 
 -         t.setHashValueSerializer(ByteArrayRedisSerializer.INSTANCE);
 
 -         t.afterPropertiesSet();
 
 -         return t;
 
 -     }
 
 - }
 
  复制代码 Controller:上传/下载二进制 
- package com.example.web;
 
  
- import org.springframework.http.*;
 
 - import org.springframework.web.bind.annotation.*;
 
 - import org.springframework.beans.factory.annotation.Autowired;
 
 - import org.springframework.data.redis.core.RedisTemplate;
 
  
- import java.time.Duration;
 
  
- @RestController
 
 - @RequestMapping("/bin")
 
 - public class BinaryController {
 
  
-     @Autowired
 
 -     private RedisTemplate<String, byte[]> binaryRedisTemplate;
 
  
-     @PutMapping("/{key}")
 
 -     public ResponseEntity<Void> put(@PathVariable String key,
 
 -                                     @RequestBody byte[] body,
 
 -                                     @RequestParam(name = "ttl", required = false) Long ttlSec) {
 
 -         if (ttlSec != null && ttlSec > 0) {
 
 -             binaryRedisTemplate.opsForValue().set(key, body, Duration.ofSeconds(ttlSec));
 
 -         } else {
 
 -             binaryRedisTemplate.opsForValue().set(key, body);
 
 -         }
 
 -         return ResponseEntity.accepted().build();
 
 -     }
 
  
-     @GetMapping("/{key}")
 
 -     public ResponseEntity<byte[]> get(@PathVariable String key) {
 
 -         byte[] data = binaryRedisTemplate.opsForValue().get(key);
 
 -         if (data == null) return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
 
 -         HttpHeaders h = new HttpHeaders();
 
 -         h.setContentType(MediaType.APPLICATION_OCTET_STREAM);
 
 -         h.setContentLength(data.length);
 
 -         return new ResponseEntity<>(data, h, HttpStatus.OK);
 
 -     }
 
 - }
 
  复制代码 启动类 
- package com.example;
 
  
- import org.springframework.boot.SpringApplication;
 
 - import org.springframework.boot.autoconfigure.SpringBootApplication;
 
  
- @SpringBootApplication
 
 - public class RedisBinaryDemoApplication {
 
 -     public static void main(String[] args) {
 
 -         SpringApplication.run(RedisBinaryDemoApplication.class, args);
 
 -     }
 
 - }
 
  复制代码 Java 8 客户端调用示例(使用 RestTemplate) 
- // 普通 Java 项目或测试里使用
 
 - import org.springframework.http.*;
 
 - import org.springframework.web.client.RestTemplate;
 
  
- import java.nio.file.Files;
 
 - import java.nio.file.Paths;
 
  
- public class ClientDemo {
 
 -     public static void main(String[] args) throws Exception {
 
 -         RestTemplate rt = new RestTemplate();
 
  
-         // 上传二进制
 
 -         byte[] bytes = Files.readAllBytes(Paths.get("D:/tmp/image.png"));
 
 -         HttpHeaders h = new HttpHeaders();
 
 -         h.setContentType(MediaType.APPLICATION_OCTET_STREAM);
 
 -         HttpEntity<byte[]> req = new HttpEntity<>(bytes, h);
 
 -         rt.exchange("http://localhost:8080/bin/pic1?ttl=3600", HttpMethod.PUT, req, Void.class);
 
  
-         // 下载二进制
 
 -         ResponseEntity<byte[]> resp = rt.getForEntity("http://localhost:8080/bin/pic1", byte[].class);
 
 -         if (resp.getStatusCode().is2xxSuccessful()) {
 
 -             Files.write(Paths.get("D:/tmp/out.png"), resp.getBody());
 
 -         }
 
 -     }
 
 - }
 
  复制代码- 用 curl 调用也行:
 
- 上传:curl -X PUT --data-binary @image.png "http://localhost:8080/bin/pic1?ttl=3600"
 - 下载:curl -o out.png "http://localhost:8080/bin/pic1"
 
 
  
  
 |   
 
 
 
 |