No meu Spring Boot
ambiente eu estava testando alguns API
. De Service
estou retornando ResponseEntity
.
Entretanto, quando tento coletar o corpo dele em controller
sala de aula, recebo uma exceção.
Método de classe de serviço:
@Service
public class RedisDemo {
private final RedisTemplate<String, String> redisTemplate;
@Autowired
public RedisDemo(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public Object executeCommand(String command, byte[]... parts) {
return redisTemplate.execute(connection ->
connection.execute(command, parts),
true
);
}
public ResponseEntity<?> test(){
Object object = executeCommand(
"HMGET",
"students".getBytes(),
"andrew".getBytes()
);
ArrayList list = (ArrayList) object;
return new ResponseEntity<>(list.get(0),HttpStatus.OK);
}
Método da classe Controller:
@GetMapping("/test")
public ResponseEntity<?> test(){
ResponseEntity<?> test = redisDemo.test();
//String body = (String)test.getBody();
//System.out.println(body);
return new ResponseEntity<>(test.getBody(),HttpStatus.OK);
}
Eu consigo obter resposta no carteiro como
andrew;wilson;abcSchool;900
No entanto, para obter o corpo da resposta, se eu descomentei a String body
linha no controlador. Estou recebendo a exceção abaixo:
java.lang.ClassCastException: class [B cannot be cast to class java.lang.String ([B and java.lang.String are in module java.base of loader 'bootstrap')
at com.self.student.controller.MainController.test(MainController.java:113) ~[classes/:na]
Como posso obter String
resposta em linha para responseEntity.getBody()
que eu possa fazer alguma lógica. Estou obtendo HMGET
resposta deredis server
Tenho que usar Jackson
a biblioteca internamente ou usando ObjectMapper
. Como usar qualquer uma delas se houver uma solução usando-as.
Acho que você está se perguntando,
Por que esse código funciona e retorna a resposta correta? -> Bem, é por causa desta linha:
Na verdade, esse código não gera nenhum erro ao ser executado de forma independente porque ele apenas encaminha test.getBody() (que é um byte[]) sem nenhuma conversão de tipo. O Spring cuida disso assim:
Verificando o tipo de dados : test.getBody() é um byte[] e é extraído do Redis usando redisTemplate.execute().
Manipulando com HttpMessageConverter : Spring automaticamente escolhe ByteArrayHttpMessageConverter para processar o byte[]. Este conversor envia os dados brutos em formato binário, com Content-Type definido como application/octet-stream por padrão.
Exibindo no lado do cliente : O Postman obtém os dados binários, os reconhece como uma string UTF-8 (como "andrew;wilson;abcSchool;900") e os exibe apenas como texto.
Sobre seu erro:
Isso acontece porque os dados retornados do Redis (via redisTemplate.execute) são, na verdade, um byte[] ([B em Java), não uma String.
Por que isso acontece?
list.get(0) é um byte[], não uma String.
Quando você tenta converter test.getBody() para String no seu controlador, o Java gera um erro porque você não pode converter byte[] diretamente para String.
Solução: converter byte[] em string antes de retorná-la
Resultado final
Agora, quando você chamar a API usando o Postman, você ainda obterá: "andrew;wilson;abcSchool;900"
Mas desta vez, seu controlador está lidando com isso como uma String adequada
Sobre seu erro:
A exceção ocorre porque o corpo da resposta do seu comando Redis é, na verdade, um array de bytes (
byte[]
), não uma String. Quando você o converte diretamente para uma String, ele falha. Você simplesmente precisa converter o array de bytes em uma String.