Display a byte[] image from a REST web service
Tech-Today

Display a byte[] image from a REST web service


This tutorial will not delve into angular nor will we discuss what a directive is. We will not try to explain what a rest web service is. Instead we will provide a demonstration via actual code, how we can consume a rest service from angular that returns an array of byte and display it as an image. We will also provide a default image in case the web service fails to return a valid image.
There are many ways to do it, but I chose a directive because of its simplicity.

Here's the directive code:

import {Directive, OnInit, Input} from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import {HttpClient} from '@angular/common/http';
import { DomSanitizer, } from '@angular/platform-browser';
import { environment } from 'environments/environment';

import { Logger } from "angular2-logger/core";

/**
* Usage:
*
* <img [image-loader]="object.id" [file]="file" imageType="VENDOR_PROFILE" />
*/
@Directive({
selector: '[image-loader]',
host: {
'[src]': 'sanitizer.bypassSecurityTrustUrl(imageData)'
}
})
export class ImageLoaderDirective implements OnInit {

url: string;
apiUrl: string
imageData: any;
@Input('image-loader') vendorId: number;
@Input('imageType') imageType: string;

constructor(private http: HttpClient, private sanitizer: DomSanitizer, private logger: Logger) {
this.apiUrl = environment.apiUrl;
}

ngOnInit() {
this.imageData = 'assets/images/missing-image.jpg';

if (this.vendorId && this.imageType) {
if (this.imageType == 'VENDOR_PROFILE') {
this.url = environment.imageType[this.imageType].replace("{id}", "" + this.vendorId);
}

this.url = this.apiUrl + this.url
this.http.get<any>(this.url)
.subscribe(
data => {
let mimeType = data.mimeType;
this.imageData = 'data:' + mimeType + ';base64,' + data.imageContent;
},
(err: HttpErrorResponse) => {
if (err.status != 200) {
if (this.imageType == 'VENDOR_PROFILE') {
this.imageData = 'assets/images/missing-vendor-profile.jpg';
} else {
this.imageData = 'assets/images/missing-image.jpg';
}
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.log('Error fetching image:', err.error.message);
} else {
// normally this happens if the object returned is not of json format
// this can cause quite the trouble
console.log(`Error fetching image: code=${err.status}, message=${err.error}`);
}
}
}
);
}

}
}

Sample usage is defined at the top of the code. What it does is it accepts an id and imageType as parameters. We use the id to get the image from the rest service; imageType is used to construct different url depending on its value. This is so we can reused this directive.

The rest service:


// rest interface
@GET
@Path("/{id}/profileImage")
Response profileImage(@PathParam("id") Long id);

// implementing rest class
@Override
public Response profileImage(Long id) {
Response.ResponseBuilder responseBuilder = null;

try {
responseBuilder = Response.ok();
responseBuilder.entity(vendorApi.profileImage(id, httpServletResponse));

} catch (Exception e) {
responseBuilder = processException(e);
}

Response response = responseBuilder.build();
log.debug("RESPONSE={}", response.getEntity());
return response;
}

// get the image
public ImageDto profileImage(Long id, HttpServletResponse response) {
Vendor vendor = vendorRepository.findById(id);
if (vendor == null || StringUtils.isBlank(vendor.getProfileImageFile())) {
throw new EntityDoesNotExistsException(Vendor.class, id);
}

File file = new File(getAppRootDir() + File.separator + id + File.separator + vendor.getProfileImageFile());
if (!file.exists()) {
throw new FileDoesNotExistsException("File does not exists: " + file.getPath());
}

try {
String encodeImage = Base64.getEncoder().withoutPadding().encodeToString(Files.readAllBytes(file.toPath()));
ImageDto imageDto = new ImageDto();
imageDto.setImageContent(encodeImage);
imageDto.setMimeType(ImageUtils.probeMimeType(file));

return imageDto;
} catch (IOException e) {
throw new BusinessApiException("Error fetching file: " + file.getName() + ". " + e.getMessage());
}
}
The last method accepts the object id, and use it to query the object that contains the filename of the image. We get the image path and convert it to byte[] using Base64 class. Note that we use a dto to store the byte[] and mimeType, this will let us return the information as json, instead of just returning a byte[], which often caused problem. Also note that we send the mimeType, we need it when displaying the image.




- Secure Angular4 With Keycloak Role Or Group
Demo template is available for sale for $50. You can send payment via skype at: [email protected] This article will be an extension of an existing one: http://czetsuya-tech.blogspot.com/2017/10/how-to-secure-angular-app-using.html. Normally in the...

- Secure Angular4 App With Keycloak
Demo template is available for sale for $50. You can send payment via skype at: [email protected] Disclaimer: This is not a tutorial on how to setup an Angular^4 project, nor are we going to discuss how to setup a Keycloak server. Needless to say, you...

- How To Download A File In Soap Api
First we define the interface like this: @WebMethod ActionStatus downloadFile(@WebParam(name = "file") String file); Implementation: public ActionStatus downloadFile(String filePath) { MessageContext mc = webServiceContext.getMessageContext(); // see...

- How To Download A File Using Rest Api
Normally I create an interface when defining a REST api, this is useful when testing using Arquillian. To define a download file api we must define the method below in the interface. @GET @Path("/downloadFile") ActionStatus downloadFile(@QueryParam("file")...

- How To Implement An Image Streamer For Primefaces Graphicimage Component
This page provide code samples for using primefaces graphic image component. In this case we are assuming that the byte data of an image is stored in an entity and that entity is access by its id. See the param id in #1. The param id is read by the streamer...



Tech-Today








.