I'm trying to do Full-stack website by myself. I'm spring developer and I'm trying to learn Angular. My code is working but it is very slow. I upload a photo to the program but it can not appear, sometimes it takes 40 - 60 seconds. I think it isn't normal, when I clicked the upload button it is saved in a database but it won't show up in the front end web page.
Below are the code for both my back and front ends. Has anyone had this problem before?
<div class="row">
<!-- Product Image -->
<div class="col-md-6 product-image">
<img *ngIf="product.imageUrl; else uploadPhoto" [src]="product.imageUrl" class="img-fluid rounded shadow-lg">
<div *ngIf="isLoading" class="loading-overlay">
<div class="spinner"></div>
</div>
<ng-template #uploadPhoto>
<div class="upload-container">
<label class="upload-photo-btn">
<input type="file" (change)="onFileSelected($event)" id="photoUpload" hidden>
<span>Upload Photo</span>
</label>
</div>
</ng-template>
</div>
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
if (input?.files?.length) {
const file = input.files[0];
// When the loading starts, we set isLoading to true
this.isLoading = true;
// We call the photo upload service
this.productService.uploadPhoto(this.product.id, file).subscribe({
next: (response) => {
// If the photo is successfully uploaded, we update the URL
this.product.imageUrl = response;
console.log("Photo uploaded successfully: ", response);
},
error: (error) => {
// In case of an error, we show the correct error message to the user
this.isLoading = false; // We hide the spinner when an error occurs
if (error.status === 400) {
alert('The file format is invalid or the file is too large. Please try again.');
} else if (error.status === 500) {
alert('A server error occurred. Please try again later.');
} else {
alert('There was an error trying to load the photo. Please try again.');
}
console.error("An error occurred while uploading the photo: ", error);
},
complete: () => {
// After the installation process is completed, we hide the spinner
this.isLoading = false;
}
});
}
}
uploadPhoto(productId:number, file:File) : Observable<string> {
const formData = new FormData();
formData.append('file',file,file.name);
return this.http.post<string>(`http://localhost:8080/v1/photos/upload/${productId}`, formData,{responseType: 'text' as 'json' });
}
Application properties:
server.tomcat.connection-timeout=60s
spring.servlet.multipart.max-file-size=3MB
spring.servlet.multipart.max-request-size=3MB
file.upload-dir = src/main/resources/static/uploads
@RestController
@RequestMapping("/v1/photos")
public class FileStorageController {
private final FileStorageService fileStorageService;
private final ProductRepository productRepository;
public FileStorageController(FileStorageService fileStorageService, ProductRepository productRepository) {
this.fileStorageService = fileStorageService;
this.productRepository = productRepository;
}
@PostMapping("/upload/{id}")
public ResponseEntity<String> uploadfile(@PathVariable int id, @RequestParam("file") MultipartFile multipartFile){
try {
Product product = productRepository.findById(id).orElseThrow(() -> new IdNotFoundException(id));
String photoUrl = fileStorageService.saveFile(multipartFile);
product.setImageUrl(photoUrl);
productRepository.save(product);
return ResponseEntity.ok(photoUrl);
}catch (Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + e.getMessage());
}
}
}
@Service
public class FileStorageService {
private final String uploadDir;
private final long MAX_FILE_SIZE = 3 * 1024 * 1024 ;
// Constructor with @Value to read upload directory from application.properties
public FileStorageService(@Value("${file.upload-dir}") String uploadDir) {
this.uploadDir = Paths.get(uploadDir).toAbsolutePath().toString();
}
public String saveFile(MultipartFile file) throws IOException {
if (file.isEmpty()) {
throw new RuntimeException("File is empty!");
}
if(file.getSize() > MAX_FILE_SIZE){
throw new RuntimeException("File size exceeds the maximum allowed size of 3 MB.");
}
// Generate a unique file name
String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
Path filePath = Paths.get(uploadDir, fileName);
// Create directories if they don't exist
Files.createDirectories(filePath.getParent());
Files.write(filePath, file.getBytes());
return "/uploads/" + fileName;
}
}
I'd like to solve this problem to make my web application faster.
After a couple of weeks of research, I realized that I don't get an error when I upload PNG format. The issue occurs when I try to upload JPEG format.Problem solved