In my Spring Boot
environment I was testing some API
. From Service
I am returning ResponseEntity
.
However when I try to collect its body in controller
class, I am getting exception.
Service class method:
@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);
}
Controller class method:
@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);
}
I am able to get response in postman as
andrew;wilson;abcSchool;900
However, in order to get response body, if I uncomment the String body
line in controller. I am getting below exception :
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]
How can I get String
response inline as responseEntity.getBody()
so that I can do some logic. I am getting HMGET
response from redis server
Do I have to use Jackson
library internally, or using ObjectMapper
. How to use any of them if there can be a solution using them.
I think you're wondering,
public ResponseEntity<?> test() {
ResponseEntity<?> test = redisDemo.test();
return new ResponseEntity<>(test.getBody(), HttpStatus.OK);
}
Why does this code work and return correct response? -> Well, it's because of this line:
return new ResponseEntity<>(test.getBody(), HttpStatus.OK);
Actually, this code doesn’t throw any errors when running standalone because it just forwards test.getBody() (which is a byte[]) without any type casting. Spring takes care of it like this:
Checking the data type: test.getBody() is a byte[], and it's pulled from Redis using redisTemplate.execute().
Handling with HttpMessageConverter: Spring automatically picks ByteArrayHttpMessageConverter to process the byte[]. This converter sends the raw data in binary format, with Content-Type set to application/octet-stream by default.
Showing it on the client side: Postman gets the binary data, recognizes it as a UTF-8 string (like "andrew;wilson;abcSchool;900"), and just displays it as text.
About Your Error:
java.lang.ClassCastException: class [B cannot be cast to class java.lang.String
This happens because the data returned from Redis (via redisTemplate.execute) is actually a byte[] ([B in Java), not a String.
Why Does This Happen?
list.get(0) is a byte[], not a String.
When you try to cast test.getBody() to String in your controller, Java throws an error because you can't directly cast byte[] to String.
Solution: Convert byte[] to String Before Returning It
public ResponseEntity<?> test() {
...
// Convert byte[] to String
String result = new String((byte[]) list.get(0), StandardCharsets.UTF_8);
return new ResponseEntity<>(result, HttpStatus.OK);
}
Final Output
Now, when you call the API using Postman, you'll still get: "andrew;wilson;abcSchool;900"
But this time, your controller is handling it as a proper String