There's a Mail API I gotta use and I'm not able to send information through my Spring application. When I copy/paste the 'body' of my HttpEntity on Postman it delivers perfectly but with RestTemplate seems to not be working. I've even tried to make a toString method to match the format of the PostMan call but even like that it's not working. These are my Java class and toString methods:
@Builder
public class CreateAndQueueMailRq {
private String application;
private String bcc;
private String body;
private String cc;
private String creationDate;
private String creationUser;
private String from;
private String fromName;
private String id;
private String market;
private String subject;
private String system;
private String to;
private String language;
private String type;
private String attachmentType;
private String attachmentFileName;
private byte[] content;
@Override
public String toString() {
return "{\"application\":\"" + application + "\","
+ "\"bcc\":\"" + bcc + "\","
+ "\"body\":\"" + body + "\","
+ "\"cc\":\"" + cc + "\","
+ "\"creationDate\":\"" + creationDate + "\","
+ "\"creationUser\":\"" + creationUser + "\","
+ "\"from\":\"" + from + "\","
+ "\"fromName\":\"" + fromName + "\","
+ "\"id\":\"" + id + "\","
+ "\"market\":\"" + market + "\","
+ "\"subject\":\"" + subject + "\","
+ "\"system\":\"" + system + "\","
+ "\"to\":\"" + to + "\","
+ "\"language\":\"" + language + "\","
+ "\"type\":\"" + type + "\","
+ "\"attachmentType\":\"" + attachmentType + "\","
+ "\"attachmentFileName\":\"" + attachmentFileName + "\","
+ "\"content\":" + Arrays.toString(content) + "}";
}
And that's how I'm performing my call:
public boolean sendMailWithAttachment(String body, String from, String fromName,
String id, String subject, String to, String language,
String filename, byte[] content, String cc, String bcc){
CreateAndQueueMailRq createAndQueueMailRq = CreateAndQueueMailRq.builder()
.application("appname")
.bcc("")
.body(body)
.cc("samplemail@gmail.com")
.creationDate(LocalDateTime.now().format(FORMATTER))
.creationUser(MailManagerConstants.COMING2)
.from(from)
.fromName(fromName)
.id(id)
.market("market_default")
.subject(subject)
.system("system_default")
.to("samplemail@gmail.com")
//.to("samplemail@gmail.com")
.language("ES")
.type(DEFAULT_TYPE)
.attachmentType(MailManagerConstants.TYPE_PDF)
.attachmentFileName(filename)
.content(content)
.build();
return generateRequest(createAndQueueMailRq, API_MAIL_MANAGER_WITH_ATTACHMENT);
}
private boolean generateRequest(CreateAndQueueMailRq createAndQueueMailRq, String api) {
//ObjectMapper objectMapper = new ObjectMapper();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
try {
//HttpEntity<String> request = new HttpEntity<>(objectMapper.writeValueAsString(createAndQueueMailRq), headers);
HttpEntity<CreateAndQueueMailRq> request = new HttpEntity<>(createAndQueueMailRq, headers);
System.out.println("Request: "+request.getBody());
ResponseEntity<?> response = restTemplate.exchange(api, HttpMethod.POST, request, String.class);
LOGGER.info(SUCCESS_MESSAGE);
return true;
}catch (HttpClientErrorException e){
LOGGER.info("STATUS CODE: "+e.getStatusCode());
LOGGER.info("RESPONSE BODY: "+e.getResponseBodyAsString());
LOGGER.info(ERROR_MESSAGE);
return false;
}
}
If I copyPaste the e.getResponseBodyAsString(), it works on Postman.
The issue is with the content byte[].
UPDATE: Creating a custom converter solved it.
public class MailManagerCustomConverter extends GsonHttpMessageConverter {
@Override
protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
if (object instanceof byte[]) {
byte[] bytes = (byte[]) object;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < bytes.length; i++) {
if (i > 0) {
sb.append(",");
}
sb.append(bytes[i]);
}
sb.append("]");
outputMessage.getBody().write("\"content\":".getBytes());
outputMessage.getBody().write(sb.toString().getBytes());
} else {
super.writeInternal(object, outputMessage);
}
}
}
To print "content":[37,40,30...] instead of "content":"[37,40,30...]"
Just explicitly provide the string when constructing the HttpEntity
instance:
HttpEntity<String> request = new HttpEntity<>(createAndQueueMailRq.toString(), headers);