Storing files indexed by a database (#10174)
Creating the FileLocationService to link the FileSystemRepository to the ImageDbRepository. Removing test order Changing to BDDMockito Changing Long wrapper for @id. Changing the test names to given-when-then pattern Co-authored-by: Gilvan Ornelas Fernandes Filho <gilvan.fernandes@bairesdev.com>
This commit is contained in:
parent
1346d5f0c5
commit
d4a8a33604
@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class FileLocationService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileSystemRepository fileSystemRepository;
|
||||||
|
@Autowired
|
||||||
|
ImageDbRepository imageDbRepository;
|
||||||
|
|
||||||
|
Long save(byte[] bytes, String imageName) throws Exception {
|
||||||
|
String location = fileSystemRepository.save(bytes, imageName);
|
||||||
|
|
||||||
|
return imageDbRepository.save(new Image(imageName, location))
|
||||||
|
.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemResource find(Long imageId) {
|
||||||
|
Image image = imageDbRepository.findById(imageId)
|
||||||
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
|
|
||||||
|
return fileSystemRepository.findInFileSystem(image.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("file-system")
|
||||||
|
class FileSystemImageController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileLocationService fileLocationService;
|
||||||
|
|
||||||
|
@PostMapping("/image")
|
||||||
|
Long uploadImage(@RequestParam MultipartFile image) throws Exception {
|
||||||
|
return fileLocationService.save(image.getBytes(), image.getOriginalFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/image/{imageId}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||||
|
FileSystemResource downloadImage(@PathVariable Long imageId) throws Exception {
|
||||||
|
return fileLocationService.find(imageId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
class FileSystemRepository {
|
||||||
|
|
||||||
|
String RESOURCES_DIR = FileSystemRepository.class.getResource("/")
|
||||||
|
.getPath();
|
||||||
|
|
||||||
|
String save(byte[] content, String imageName) throws Exception {
|
||||||
|
Path newFile = Paths.get(RESOURCES_DIR + new Date().getTime() + "-" + imageName);
|
||||||
|
Files.createDirectories(newFile.getParent());
|
||||||
|
|
||||||
|
Files.write(newFile, content);
|
||||||
|
|
||||||
|
return newFile.toAbsolutePath()
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystemResource findInFileSystem(String location) {
|
||||||
|
try {
|
||||||
|
return new FileSystemResource(Paths.get(location));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Handle access or file not found problems.
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class Image {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
|
||||||
|
String location;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
byte[] content;
|
||||||
|
|
||||||
|
public Image() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image(String name, String location) {
|
||||||
|
this.name = name;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(byte[] content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(String location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ImageArchiveApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ImageArchiveApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Slf4j
|
||||||
|
class ImageController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ImageDbRepository imageDbRepository;
|
||||||
|
|
||||||
|
@PostMapping("/image")
|
||||||
|
long uploadImage(@RequestParam MultipartFile multipartImage) throws IOException {
|
||||||
|
Image dbImage = new Image();
|
||||||
|
dbImage.setName(multipartImage.getOriginalFilename());
|
||||||
|
dbImage.setContent(multipartImage.getBytes());
|
||||||
|
|
||||||
|
return imageDbRepository.save(dbImage)
|
||||||
|
.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/image/{imageId}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||||
|
Resource downloadImage(@PathVariable Long imageId) {
|
||||||
|
byte[] image = imageDbRepository.findById(imageId)
|
||||||
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND))
|
||||||
|
.getContent();
|
||||||
|
|
||||||
|
return new ByteArrayResource(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface ImageDbRepository extends JpaRepository<Image, Long> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
@SpringBootTest(classes = ImageArchiveApplication.class)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
class FileSystemImageIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
FileLocationService fileLocationService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenJpegImage_whenUploadIt_thenReturnItsId() throws Exception {
|
||||||
|
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
InputStream image = classLoader.getResourceAsStream("baeldung.jpeg");
|
||||||
|
|
||||||
|
MockMultipartHttpServletRequestBuilder multipartRequest = MockMvcRequestBuilders.multipart("/file-system/image")
|
||||||
|
.file(new MockMultipartFile("image", "baeldung", MediaType.TEXT_PLAIN_VALUE, image));
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(multipartRequest)
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
assertThat(result.getResponse()
|
||||||
|
.getContentAsString())
|
||||||
|
.isEqualTo("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenBaeldungImage_whenDownloadIt_thenReturnTheImage() throws Exception {
|
||||||
|
given(fileLocationService.find(1L))
|
||||||
|
.willReturn(baeldungJpegResource());
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.get("/file-system/image/1")
|
||||||
|
.contentType(MediaType.IMAGE_JPEG_VALUE))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileSystemResource baeldungJpegResource() {
|
||||||
|
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
String imagePath = classLoader.getResource("baeldung.jpeg")
|
||||||
|
.getFile();
|
||||||
|
|
||||||
|
return new FileSystemResource(Paths.get(imagePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.baeldung.db.indexing;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
@SpringBootTest(classes = ImageArchiveApplication.class)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
class ImageIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
ImageDbRepository imageRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenBaeldungJpegImage_whenUploadIt_thenReturnItsId() throws Exception {
|
||||||
|
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
InputStream image = classLoader.getResourceAsStream("baeldung.jpeg");
|
||||||
|
|
||||||
|
MockMultipartHttpServletRequestBuilder multipartRequest = MockMvcRequestBuilders.multipart("/image")
|
||||||
|
.file(new MockMultipartFile("image", "baeldung", MediaType.TEXT_PLAIN_VALUE, image));
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(multipartRequest)
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
assertThat(result.getResponse()
|
||||||
|
.getContentAsString())
|
||||||
|
.isEqualTo("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenExistingImage_whenDownloadIt_thenReturnHttpStatusOk() throws Exception {
|
||||||
|
given(imageRepository.findById(1L))
|
||||||
|
.willReturn(Optional.of(baeldungImage()));
|
||||||
|
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
|
.get("/image/1")
|
||||||
|
.contentType(MediaType.IMAGE_JPEG_VALUE))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image baeldungImage() throws IOException {
|
||||||
|
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
|
||||||
|
Image mockImage = new Image();
|
||||||
|
mockImage.setContent(Files.readAllBytes(Paths.get(classLoader.getResource("baeldung.jpeg")
|
||||||
|
.getFile())));
|
||||||
|
return mockImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
Loading…
x
Reference in New Issue
Block a user