US10: Make it possible for horse information to be displayed on the view page, add a get image method to the API
This commit is contained in:
parent
3cc36466df
commit
4be964b537
@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
@ -146,4 +147,24 @@ public class HorseEndpoint {
|
||||
"Something went wrong while uploading the file");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/image/{path}", produces = {MediaType.IMAGE_JPEG_VALUE,MediaType.IMAGE_PNG_VALUE}, method=RequestMethod.GET)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public @ResponseBody byte[] getImage(@PathVariable("path") String path) {
|
||||
// Get the image as byte array and return it with a media type assigned
|
||||
// https://www.baeldung.com/spring-controller-return-image-file
|
||||
// https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/MediaType.html
|
||||
LOGGER.info("GET " + BASE_URL + "/image/{}", path);
|
||||
try {
|
||||
return horseService.getImage(path);
|
||||
} catch(ValidationException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
|
||||
"Unsupported file type provided. Supported file types are jpg and png.");
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND,
|
||||
"Something went wrong while reading the file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,4 +18,12 @@ public interface FileDao {
|
||||
* @throws IOException if something goes wrong with deleting the file
|
||||
*/
|
||||
void delete(String fileName) throws IOException;
|
||||
|
||||
/**
|
||||
* Used fot getting a file from the local filesystem
|
||||
* @param fileName of the file to open
|
||||
* @return the file as bytes
|
||||
* @throws IOException if something goes wrong during file access
|
||||
*/
|
||||
byte[] get(String fileName) throws IOException;
|
||||
}
|
||||
|
@ -63,4 +63,21 @@ public class HorseFileDao implements FileDao {
|
||||
throw new IOException("Deleting the file specified failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(String fileName) throws IOException {
|
||||
if(fileName == null || fileName.equals(""))
|
||||
throw new IOException("Cannot open an unexisting file");
|
||||
|
||||
LOGGER.trace("Getting file from " + FILE_BASE_PATH + fileName);
|
||||
try {
|
||||
// Read the file and return a byte array
|
||||
// https://stackoverflow.com/a/5083666
|
||||
File imageFile = new File(FILE_BASE_PATH + fileName);
|
||||
return Files.readAllBytes(imageFile.toPath());
|
||||
} catch(Exception e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
throw new IOException("Opening the file specified failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,4 +64,12 @@ public interface HorseService {
|
||||
* @throws ValidationException will be thrown if the file is in the incorrect format
|
||||
*/
|
||||
void saveImage(MultipartFile img) throws IOException, ValidationException;
|
||||
|
||||
/**
|
||||
* @param path of the image to get
|
||||
* @return the image
|
||||
* @throws IOException will be thrown if the file could not be accessed
|
||||
* @throws ValidationException will be thrown if the path does not end with .jpg, .jpeg or .png
|
||||
*/
|
||||
byte[] getImage(String path) throws IOException, ValidationException;
|
||||
}
|
||||
|
@ -78,4 +78,11 @@ public class SimpleHorseService implements HorseService {
|
||||
LOGGER.trace("saveImage({})", img.getName());
|
||||
horseFileDao.save(img);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getImage(String path) throws IOException, ValidationException {
|
||||
this.validator.validateImageRequest(path);
|
||||
LOGGER.trace("getImage({})", path);
|
||||
return horseFileDao.get(path);
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,15 @@ public class Validator {
|
||||
}
|
||||
}
|
||||
|
||||
public void validateImageRequest(String path) throws ValidationException {
|
||||
if(path == null || path.isEmpty()) {
|
||||
throw new ValidationException("No image path supplied");
|
||||
}
|
||||
if(!path.endsWith(".png") && !path.endsWith(".jpg") && !path.endsWith(".jpeg")) {
|
||||
throw new ValidationException("Unsupported file extension supplied.");
|
||||
}
|
||||
}
|
||||
|
||||
public void validateHorseFilter(Map<String, String> filters) throws ValidationException {
|
||||
if(filters.get("score") != null) {
|
||||
try {
|
||||
|
@ -6,12 +6,40 @@
|
||||
</div>
|
||||
|
||||
<div class="container mt-3" *ngIf="horse">
|
||||
<div class="alert alert-success" role="alert">
|
||||
<h4 class="alert-heading">Well done!</h4>
|
||||
<p>Your application is up and running</p>
|
||||
<h1>Horse Info for {{ horse.name }}</h1>
|
||||
<hr>
|
||||
<p>This is the name of the horse with id 1 from your backend system:
|
||||
<span class="font-weight-bold">{{horse.name}}</span>
|
||||
</p>
|
||||
<div class="row">
|
||||
<img class="img-thumbnail float-left col-md-6" src="http://localhost:8080/horses/image/{{ horse.imagePath }}" *ngIf="horse.imagePath">
|
||||
<table class="table table-striped float-right col-md-6">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Name</th>
|
||||
<td>{{ horse.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Owner</th>
|
||||
<td>
|
||||
<a href="owner/{{ horse.owner }}" *ngIf="horse.owner; else noOwner">{{ ownerName }}</a>
|
||||
<ng-template #noOwner> {{ ownerName }} </ng-template>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Birthday</th>
|
||||
<td>{{ horse.birthday }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Race</th>
|
||||
<td>{{ horse.race }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Score</th>
|
||||
<td>{{ horse.score }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Description</th>
|
||||
<td>{{ horse.description }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { HorseService } from '../../service/horse.service';
|
||||
import { Horse } from '../../dto/horse';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { OwnerService } from 'src/app/service/owner.service';
|
||||
import { Owner } from 'src/app/dto/owner';
|
||||
|
||||
@Component({
|
||||
selector: 'app-horse',
|
||||
@ -13,8 +15,9 @@ export class HorseComponent implements OnInit {
|
||||
error = false;
|
||||
errorMessage = '';
|
||||
horse: Horse;
|
||||
ownerName: string;
|
||||
|
||||
constructor(private horseService: HorseService, private route: ActivatedRoute) { }
|
||||
constructor(private horseService: HorseService, private route: ActivatedRoute, private ownerService: OwnerService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
// Extract id from url
|
||||
@ -37,6 +40,7 @@ export class HorseComponent implements OnInit {
|
||||
this.horseService.getHorseById(id).subscribe(
|
||||
(horse: Horse) => {
|
||||
this.horse = horse;
|
||||
this.loadOwnerNameForHorse(horse.owner);
|
||||
},
|
||||
error => {
|
||||
this.defaultServiceErrorHandling(error);
|
||||
@ -44,6 +48,23 @@ export class HorseComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the name of the owner of a horse
|
||||
* @param id of the owner to get
|
||||
*/
|
||||
private loadOwnerNameForHorse(id: number) {
|
||||
this.ownerService.getOwnerById(id).subscribe(
|
||||
(owner: Owner) => {
|
||||
console.log(owner.name)
|
||||
this.ownerName = owner.name;
|
||||
console.log(this.ownerName);
|
||||
},
|
||||
error => {
|
||||
this.ownerName = "N/A";
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private defaultServiceErrorHandling(error: any) {
|
||||
console.log(error);
|
||||
this.error = true;
|
||||
|
Reference in New Issue
Block a user