Reputation: 1620
These are two SpringBoot projects. A is for api service providing, and B is consuming A's service via rest template. It is OK while transferring string. While transferring Excel file via byte array, B receives a string, not byte array.
The api method in A.
@GetMapping(value = "/export")
@ResponseBody
public HSResult exportFile(@RequestParam(value = "fileName", defaultValue = "-1") String fileName,
@RequestParam(value = "provider", defaultValue = "-1") String channelId,
@RequestParam(value = "fileStatus", defaultValue = "-5") int fileStatus,
@RequestParam(value = "cdate", defaultValue = "") String cdate,
HttpServletRequest request, HttpServletResponse response) {
// ...... some logic code
InputStream inputStream=new FileInputStream(fullPath);
long fileSize=new File(fullPath).length();
byte[] allBytes = new byte[(int) fileSize];
inputStream.read(allBytes);
result = HSResult.build(200, "exportFile success",allBytes);
return result;
}
The consuming method in B.
public ResponseEntity downLoadFile(int businessType, String fileName, int fileStatus, HttpServletResponse response) {
//.......
ResponseEntity<HSResult> responseEntity = restTemplate.getForEntity(url, HSResult.class);
HSResult apiResult = responseEntity.getBody();
byte[] fileData = (byte[]) apiResult.getData();
//.......
}
A reads an excel file from disk into a byte array before transferring.
But while receving the result in B side, it is string like UEsDBC0AAAAIADhMuVAKVjbC//////////8LABQAX3Jl
Why did this happen? And how to transfer byte array through rest template correctly? Thanks.
PS: The class of HSResult
public class HSResult {
private Integer status;
private String msg;
private Object data;
//gets and setters
//......
}
Upvotes: 0
Views: 4260
Reputation: 61
I have used the Gson() class to convert object to json! and it has no problem with byte arrays.
I have this problem when I want to move my codes to spring, so I solved it by serializing byte[] filed:
class ByteArraySerializer: JsonSerializer<ByteArray>() {
override fun serialize(bytes: ByteArray, jsonGenerator: JsonGenerator, serializerProvider: SerializerProvider?) {
val intArray = intArray(bytes)
jsonGenerator.writeArray(intArray, 0, intArray.size)
}
private fun intArray(input: ByteArray): IntArray {
val ret = IntArray(input.size)
for (i in input.indices) ret[i] = input[i].toInt() // & 0xff -> 0-255
return ret
}
}
convert byte array to int array
and then use it in my class:
data class VideoInfo(val durationMS: Int = 0): Serializable {
@JsonSerialize(using = ByteArraySerializer::class)
var bytes: ByteArray? = null
}
It will return json object as a below:
{
"bytes": [-1,-40, ..., 0],
"durationMS": 8870
}
It is kotlin, You can easily convert it to java :)
Upvotes: 0
Reputation: 1620
Finally, I find the root cause. Share it with who may encounter the same issue.
data
field of HSResult
, this field is in type object. HSResult
. When it comes to the byte array, the receving field data
is in type object. So rest template does not konw what the specific type it is, then convert the byte array into a string, with some decode. I don't know whether it is exactly UTF8 or GB2312 or else.How to resolve this? Just specify the receving field with specific type, not object.
public class HSResult {
private Integer status;
private String msg;
private byte[] data;
//gets and setters
}
Then everythiing is OK.
Thanks for Ken's reminder. Http is a text protocal, it cannot transfer byte array directly, so byte array must be converted into string at first.
Upvotes: 2