Add user profile picture storage service

master
dizda13 2017-04-02 22:03:18 +02:00
parent 907e0327df
commit b3144e5601
12 changed files with 228 additions and 5 deletions

2
config

@ -1 +1 @@
Subproject commit c02e79c9aad0a236f1549e849233f9b9193a025f
Subproject commit ccf6fbb013c16dbda4ce5c76de706caed5ccde72

View File

@ -1,7 +1,7 @@
server.port = 9020
spring.datasource.url = jdbc:mysql://localhost:3306/events
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.password = skorpion
spring.jpa.generate-ddl=true
user.password=dizda
#

View File

@ -1,6 +1,6 @@
server.port=9010
spring.datasource.url = jdbc:mysql://localhost:3306/teams
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.password = skorpion
spring.jpa.generate-ddl=true

View File

@ -1,9 +1,12 @@
package ba.steleks;
import ba.steleks.storage.StorageProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class SteleksServiceApplication {
public static void main(String[] args) {

View File

@ -0,0 +1,64 @@
package ba.steleks.controller;
import ba.steleks.model.User;
import ba.steleks.repository.UsersJpaRepository;
import ba.steleks.storage.StorageFileNotFoundException;
import ba.steleks.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.io.Resource;
import java.util.Date;
/**
* Created by admin on 02/04/2017.
*/
@RestController
public class ProfilePictureController {
private final StorageService storageService;
private final UsersJpaRepository repository;
@Autowired
public ProfilePictureController(StorageService storageService, UsersJpaRepository repository) {
this.storageService = storageService;
this.repository = repository;
}
@GetMapping("/profilePictures/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity
.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+file.getFilename()+"\"")
.body(file);
}
@PostMapping("/users/{userId}/profilePicture")
public String handleFileUpload(@PathVariable Long userId, @RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
String[] names = file.getOriginalFilename().split("\\.");
String dest = String.valueOf(userId + "_" + new Date().getTime()) + "." + names[names.length - 1];
storageService.store(file, dest);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
User user = repository.findOne(userId);
user.setProfilePictureUrl("http://localhost:8090/profilePictures/" + dest);
repository.save(user);
return "redirect:/";
}
@ExceptionHandler(StorageFileNotFoundException.class)
public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) {
return ResponseEntity.notFound().build();
}
}

View File

@ -24,7 +24,7 @@ public class User {
private String firstName;
@NotNull
private String lastName;
@Column(updatable = false, insertable = false, columnDefinition="DATETIME default NOW()")
@NotNull
private Timestamp registrationDate;
@NotNull
private String email;

View File

@ -0,0 +1,87 @@
package ba.steleks.storage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
@Service
public class FileSystemStorageService implements StorageService {
private final Path rootLocation;
@Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getLocation());
}
@Override
public void store(MultipartFile file, String dest) {
try {
if (file.isEmpty()) {
throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
}
Files.copy(file.getInputStream(),
this.rootLocation.resolve(dest));
} catch (IOException e) {
throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
}
}
@Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
}
@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if(resource.exists() || resource.isReadable()) {
return resource;
}
else {
throw new StorageFileNotFoundException("Could not read file: " + filename);
}
} catch (MalformedURLException e) {
throw new StorageFileNotFoundException("Could not read file: " + filename, e);
}
}
@Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
@Override
public void init() {
try {
Files.createDirectory(rootLocation);
} catch (IOException e) {
throw new StorageException("Could not initialize storage", e);
}
}
}

View File

@ -0,0 +1,12 @@
package ba.steleks.storage;
public class StorageException extends RuntimeException {
public StorageException(String message) {
super(message);
}
public StorageException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,13 @@
package ba.steleks.storage;
public class StorageFileNotFoundException extends StorageException {
public StorageFileNotFoundException(String message) {
super(message);
}
public StorageFileNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,21 @@
package ba.steleks.storage;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("storage")
public class StorageProperties {
/**
* Folder location for storing files
*/
private String location = "/Users/admin";
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

View File

@ -0,0 +1,23 @@
package ba.steleks.storage;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file, String dest);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}

View File

@ -1,6 +1,6 @@
server.port = 8090
spring.datasource.url = jdbc:mysql://localhost:3306/users
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.password = skorpion
spring.jpa.generate-ddl=true