Fakultas Ilmu Komputer UI

Commit 5f52714a authored by MUHAMMAD AAQIL ABDULLAH's avatar MUHAMMAD AAQIL ABDULLAH
Browse files

Update image to be stored in database

parent 16ed8750
Pipeline #134160 passed with stages
in 22 minutes and 57 seconds
......@@ -95,7 +95,7 @@ public class CuratorController {
@PostMapping(path={"/create-article"})
public String addArticle(@RequestParam MultipartFile image,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.createArticle(title,author,desc,image.getBytes(),image.getOriginalFilename());
articleService.createArticle(title,author,desc,image.getBytes());
return REDIRECT_ARTICLE;
}
......@@ -108,7 +108,7 @@ public class CuratorController {
@PostMapping(path={"/update/{id}"})
public String updateArticle(@PathVariable(value = "id") Integer id, @RequestParam("image") final MultipartFile image,@RequestParam String title,@RequestParam String author,@RequestParam String desc) throws IOException {
articleService.updateArticle(id, title,author,desc,image.getBytes(),image.getOriginalFilename());
articleService.updateArticle(id, title,author,desc,image.getBytes());
return REDIRECT_ARTICLE;
}
......
package id.ac.ui.cs.advprog.landiandfriends.controller;
import id.ac.ui.cs.advprog.landiandfriends.service.ImageService;
import id.ac.ui.cs.advprog.landiandfriends.service.ImageServiceImpl;
import lombok.RequiredArgsConstructor;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/image")
@RequiredArgsConstructor
public class ImageController {
private final ImageServiceImpl imageService;
@GetMapping(path = "{imageId}", produces= MediaType.IMAGE_JPEG_VALUE)
public FileSystemResource findImage(@PathVariable Long imageId){
return imageService.findImage(imageId);
}
}
......@@ -26,6 +26,9 @@ public class Articles {
@Column(nullable = false, columnDefinition ="TEXT", name = "description", length = Integer.MAX_VALUE)
private String content;
@Column(name="encode",columnDefinition="text", length=10485760)
private String img;
@Column(name="image_id")
private Long imageId;
......
......@@ -35,8 +35,8 @@ public class Book {
@Column(name = "price", nullable = false)
private float price;
@Column(name="image_id")
private Long imageId;
@Column(name="encode",columnDefinition="text", length=10485760)
private String img;
@ManyToMany
@JsonIgnore
......
package id.ac.ui.cs.advprog.landiandfriends.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "image_model")
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "image_id")
private Long imageId;
@Column(nullable = false, name = "path")
private String path;
}
......@@ -9,8 +9,8 @@ public class ArticleProductCard implements ProductCard {
private Articles article;
@Override
public Long getImageId() {
return article.getImageId();
public String getImg() {
return article.getImg();
}
@Override
......
......@@ -9,8 +9,8 @@ public class BookProductCard implements ProductCard {
private Book book;
@Override
public Long getImageId() {
return book.getImageId();
public String getImg() {
return book.getImg();
}
@Override
......
......@@ -2,7 +2,7 @@ package id.ac.ui.cs.advprog.landiandfriends.model.productcard;
public interface ProductCard {
Long getImageId();
String getImg();
String getTitle();
String getCreator();
String getInfo();
......
package id.ac.ui.cs.advprog.landiandfriends.repository;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
}
......@@ -7,8 +7,8 @@ import java.io.IOException;
import java.util.List;
public interface ArticleService {
Articles createArticle(String title, String author, String content, byte[] image, String imageName);
void updateArticle(Integer id, String title, String author, String content, byte[] image, String imageName);
Articles createArticle(String title, String author, String content, byte[] image);
void updateArticle(Integer id, String title, String author, String content, byte[] image);
List<Articles> getAllArticles();
Articles getArticle(Integer id);
List<Articles> getRandomArticles(int amount);
......
package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.model.Articles;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import id.ac.ui.cs.advprog.landiandfriends.repository.ArticleRepository;
import id.ac.ui.cs.advprog.landiandfriends.util.ImageConverter;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -18,25 +17,23 @@ import java.util.Optional;
public class ArticleServiceImpl implements ArticleService {
private final ArticleRepository repo;
private final ImageServiceImpl imageService;
private final Logger logger = LoggerFactory.getLogger(ArticleServiceImpl.class);
private void createImageForArticle(Articles article, byte[] images, String imageName){
private void createImageForArticle(Articles article, byte[] images){
try{
Image image = imageService.createImage(images, imageName);
article.setImageId(image.getImageId());
article.setImg(ImageConverter.getInstance().getString(images));
} catch (Exception e){
logger.error("Exception during image upload for article {}: {}", article.getArticleId(), e.getMessage());
}
}
@Override
public Articles createArticle(String title, String author, String content, byte[] imageBytes, String imageName) {
public Articles createArticle(String title, String author, String content, byte[] imageBytes) {
var art = new Articles();
art.setTitle(title);
art.setAuthor(author);
art.setContent(content);
createImageForArticle(art, imageBytes, imageName);
createImageForArticle(art, imageBytes);
repo.save(art);
return art;
}
......@@ -50,14 +47,14 @@ public class ArticleServiceImpl implements ArticleService {
return repo.findAll();
}
public void updateArticle(Integer id,String title,String author,String desc,byte[] image, String imageName) {
public void updateArticle(Integer id,String title,String author,String desc,byte[] image) {
Optional<Articles> art = repo.findById(id);
if(art.isPresent()){
Articles objArt = art.get();
objArt.setTitle(title);
objArt.setAuthor(author);
objArt.setContent(desc);
createImageForArticle(objArt, image, imageName);
createImageForArticle(objArt, image);
repo.save(objArt);
}
}
......
......@@ -3,9 +3,9 @@ package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.exception.InvalidStockException;
import id.ac.ui.cs.advprog.landiandfriends.forms.CreateBookForm;
import id.ac.ui.cs.advprog.landiandfriends.model.Book;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import id.ac.ui.cs.advprog.landiandfriends.repository.BookRepository;
import id.ac.ui.cs.advprog.landiandfriends.repository.GenreRepository;
import id.ac.ui.cs.advprog.landiandfriends.util.ImageConverter;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -25,7 +25,6 @@ public class BookServiceImpl implements BookService {
private final BookRepository bookRepository;
private final GenreRepository genreRepository;
private final ImageServiceImpl imageService;
private final Logger logger = LoggerFactory.getLogger(BookServiceImpl.class);
private void setBookData(Book book, CreateBookForm form, MultipartFile file){
......@@ -47,8 +46,7 @@ public class BookServiceImpl implements BookService {
if(file != null){
try{
Image image = imageService.createImage(file.getBytes(), file.getOriginalFilename());
book.setImageId(image.getImageId());
book.setImg(ImageConverter.getInstance().getString(file.getBytes()));
} catch (Exception e){
logger.error("Exception during image upload for book {}: {}", book.getBookId(), e.getMessage());
}
......
package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import org.springframework.core.io.FileSystemResource;
import java.io.IOException;
public interface ImageService {
Image createImage(byte[] imageContent, String name) throws IOException;
FileSystemResource findImage(Long id);
}
package id.ac.ui.cs.advprog.landiandfriends.service;
import id.ac.ui.cs.advprog.landiandfriends.model.Image;
import id.ac.ui.cs.advprog.landiandfriends.repository.ImageRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class ImageServiceImpl {
private final ImageRepository imageRepository;
String DIR = new File(getClass().getResource("/").getFile()).toPath().toString();
public Image createImage(byte[] imageContent, String name) throws IOException {
Path imagePath = Paths.get(DIR + new Date().getTime() + "-" + name);
Files.createDirectories(imagePath.getParent());
Files.write(imagePath, imageContent);
Image image = new Image();
image.setPath(imagePath.toAbsolutePath().toString());
imageRepository.save(image);
return image;
}
public FileSystemResource findImage(Long id){
Optional<Image> imageOpt = imageRepository.findById(id);
if(imageOpt.isPresent()){
String path = imageOpt.get().getPath();
return new FileSystemResource(Paths.get(path));
}
return null;
}
}
package id.ac.ui.cs.advprog.landiandfriends.util;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
public class ImageConverter {
private static ImageConverter imageConverter = null;
private ImageConverter() {
}
public static ImageConverter getInstance() {
if (imageConverter == null) {
imageConverter = new ImageConverter();
}
return imageConverter;
}
public String getString(byte[] content) {
return new String(Base64.encodeBase64(content));
}
}
......@@ -91,7 +91,7 @@
<div class="cards_wrap">
<div th:each="art : ${all_art}" class="card_item">
<div class="card_inner">
<img th:src="${'/image/'+art.imageId}" class="product-image" style="width: 150px">
<img th:src="|data:image;base64,*{art.getImg()}|" class="product-image" style="width: 150px">
<div th:text="${art.title}"class="role_name"></div>
<div th:text="${art.author}" class="real_name"></div>
<div class="film"><form
......
......@@ -46,7 +46,7 @@
</div>
<div class="form-group">
<p>Current Image:</p>
<img th:src="${'/image/'+book.imageId}" class="product-image" style="width: 150px"/>
<img th:src="|data:image;base64,*{book.getImg()}|" class="product-image" style="width: 150px"/>
</div>
<div class="form-group">
<label for="image">Update Image: </label>
......
......@@ -68,7 +68,6 @@
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">Stock</th>
<th scope="col">Image id</th>
</tr>
</thead>
<tbody th:each="book : ${books}" th:remove="tag">
......@@ -78,7 +77,6 @@
<td th:text="${book.title}">...</td>
<td th:text="${book.author}">...</td>
<td th:text="${book.stock}">...</td>
<td th:text="${book.imageId}">...</td>
<td>
<form onSubmit="return confirm('Are you sure you want to remove this book?') "
class="remove-book"
......
......@@ -86,7 +86,7 @@
<div class="cards_wrap">
<div th:each="product : ${products}" class="card_item">
<div class="card_inner">
<img th:src="${'/image/'+product.getImageId()}" class="product-image" style="width: 150px">
<img th:src="|data:image;base64,*{product.getImg()}|" class="product-image" style="width: 150px">
<div th:text="${product.getTitle()}"class="role_name"></div>
<div th:inline="text" class="real_name"> by [[${product.getCreator()}]]</div>
<p th:text="${product.getInfo()}"></p>
......
package id.ac.ui.cs.advprog.landiandfriends.controller;
import id.ac.ui.cs.advprog.landiandfriends.model.User;
import id.ac.ui.cs.advprog.landiandfriends.repository.UserRepository;
import id.ac.ui.cs.advprog.landiandfriends.service.ImageServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(controllers = ImageController.class)
public class ImageControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private ImageServiceImpl imageService;
@MockBean
private UserRepository userRepository;
@Test
void whenGetImagePage() throws Exception {
when(imageService.findImage(any())).thenReturn(null);
mockMvc.perform(get("/image/1"))
.andExpect(status().isOk())
.andExpect(handler().methodName("findImage"));
verify(imageService, times(1)).findImage(1L);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment