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…
Reference in New Issue