I have backend code in my application that needs the retrieved tableau view image passed to it like in the example below:
`String tableauReportBase64Encoded = getStaticImage(tableauReportService.getTableauStaticReport(tableauConstants.getReportImagePath()));
map.put("image1", tableauReportBase64Encoded);
private String getStaticImage(byte[] imageBytes) {
String base64Encoded = null;
if(imageBytes == null) {
return null;
}
byte[] encodeBase64 = Base64.encodeBase64(imageBytes);
try {
base64Encoded = new String(encodeBase64, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return base64Encoded;
}`
I decided to try this way:
`public byte[] getTableauStaticReport(String reportUrl) {
TableauCredentialsType tableauCredentials = invokeSignIn(Constants.EMPTY_STRING);
HttpGet getTableauReportImage = new HttpGet(reportUrl);
getTableauReportImage.addHeader(TableauConstants.TABLEAU_AUTH_HEADER, tableauCredentials.getToken());
byte[] tableauReportImageBytes = null;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
CloseableHttpResponse response = httpClient.execute(getTableauReportImage);
InputStream imageInput = response.getEntity().getContent();
tableauReportImageBytes = new byte[imageInput.available()];
imageInput.read(tableauReportImageBytes);
} catch (IOException e) {
e.printStackTrace();
}
invokeSignOut(tableauCredentials);
return tableauReportImageBytes;
}`
But I'm getting a NullPointerException on the jaxbMarshaller.marshal(requestPayload, writer) line of the below code that is used to sign in/make post requests to Tableau:
`private TsResponse post(String url, String authToken, TsRequest requestPayload) {
// Creates an instance of StringWriter to hold the XML for the request
StringWriter writer = new StringWriter();
// Marshals the TsRequest object into XML format if it is not null
if (requestPayload != null) {
try {
jaxbMarshaller.marshal(requestPayload, writer);
} catch (JAXBException ex) {
logger.error("There was a problem marshalling the payload");
}
}
// Converts the XML into a string
String payload = writer.toString();
logger.debug("Input payload: \n" + payload);
HttpPost post = new HttpPost(url);
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair(TableauConstants.TABLEAU_AUTH_HEADER, authToken));
String responseXML = "";
StringEntity payloadEntity = new StringEntity(payload, ContentType.TEXT_XML);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
CloseableHttpResponse response = httpClient.execute(post);
// Parses the response from the server into an XML string
HttpEntity responseEntity = response.getEntity();
responseXML = responseEntity.toString();
logger.debug("Response: \n" + responseXML);
} catch (UnsupportedEncodingException encodingException) {
encodingException.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Returns the unmarshalled XML response
return unmarshalledResponse(responseXML);
}`
I checked the requestPayload, the name and password are set properly while site, token & user are null, and the writer object has the buf & lock set but the writeBuffer is null. I have not used jaxbMarshaller/StringWriter before but it seems like the marshaller needs the writer to be writing it to a StringBuilder or other object; or is it failing via NullPointerException for another reason?
I do have another question as well: I've tried all of the tableau api get view image calls in Postman and they all work except one that is giving me a 400074 error code. I checked the Tableau site and a 400074 error is a generic query error. Would you know how to troubleshoot that and should I create a separate question/issue for that/the question below?
It seems like that view requires a tableau user to connect to the data source before being able to see the view and that is probably causing the 400074 error. Is there a way to provide those credentials in the view image request?