[JAVA] Implement image input / output with Spring MVC

See here for uploading images

Click here to upload images (https://qiita.com/shibafu/items/16dbf776bd81a40450fd)

A little detour

If you don't know Spring and your composition, I think it's a jumble, so I will explain my project a little.

アーキテクチャ.png

It has such a structure. The ** controller ** is where this server is first accessed. Each of the methods in it accepts access.

** Service ** is the place where the actual processing description of the program is stored. Let's take a look at the contents of the service. Architecture.png

The ** interface ** is the entry point for controllers and other Java programs into this service. And this is implemented in a class called hogehoge ** Impl **. (Impl means "implementation".)

Why is it necessary to separate the processing description and the entrance? Let's take a look at the description that actually calls the service

アーキテクチャ.png

First look at the program on the right It is annotated as ** @ Service **. This means that this is a "class of service" declaration and at the same time ** registering an instance in the DI container **. ** DI container ** is a function of Spring Framework, which makes Java programs ** loosely coupled **. Instances that enter the DI container are controlled by the Spring Framework to create and release instances.

What makes me happy with this is that it can be compiled even if the processing is not implemented. Let's take a look at the service call on the left.

** Interface ** declaration and It is annotated as ** @ Autowired **.

@Autowired is a command to "create a DI container registered, this type instance" (cannot be used when two or more beans of the same type are registered).

What you should pay attention to here is that ** you are not using new when you create an instance **. In other words, it is a program that can be compiled with just an empty class called an interface.

By designing the interface ** 1. I can imagine the functions to be created ** ** 2. It has the advantage that it can be compiled even if the function is not implemented **.

The structure of such a program It is said to be called the ** façade (front entrance) ** design pattern. (Strictly speaking, it seems a little different

It is like this. If you call yourself a service from now on, "processing on the service side" If you call it a controller, read it as "Oh, the first process that the server receives." The digression is over.

The main subject from here

First, register the image in the DB.

First, create an image input function using the JPA repository. This is just that, so there is no problem.

First, create a process to register the image in the DB.

pictureServiceImpl.java


	@Autowired
	PictureMasterRepository pRepository;

	@Override
	public int addPicture(byte[] picturedata, String pictureName, String originalName, Integer uploadUserId) {
		//TODO auto-generated method stub
		PictureMaster input = new PictureMaster();
		
		input.setPictureData(picturedata);
		input.setPictureName(pictureName);
		input.setOriginalName(originalName);
		input.setUploadUserId(uploadUserId);
		
		pRepository.saveAndFlush(input);
		
		return 0;

Next, create a process to read the image. Let's create access to the DB using the automatic implementation function of the JPA repository.

PictureMasterRepository.java


@Repository
public interface PictureMasterRepository extends JpaRepository<PictureMaster, Integer> {


    public PictureMaster findByPictureId(Long pictureId);
    public PictureMaster findByPictureName(String pictureName);
    

    public List<PictureMaster> findByUploadUserId(int uploadUserId);
    
    //Good search with Like
//    public List<UserMaster> findByUsernameLike(String usernamename);
//    public List<UserMaster> findByEmailLike(String email);
    
//    @Query("SELECT count(*) From UserMaster u WHERE u.username = :username")
//    public int countByUsername(@Param("username")String username);
}

pictureServiceImpl.java


	/**
	 *Returns a registered image based on user name
	 */
	@Override
	public List<PictureMaster> readUserPicture(Integer uploadUserId) {
		
	List<PictureMaster> searchResult = pRepository.findByUploadUserId(uploadUserId);
	
	return searchResult;
	
	}

I was able to perform specific processing ヾ (.> ﹏ <.) Nottater

Then, pass the created process to the controller.

ImageIOController.java



		ModelAndView mv = new ModelAndView("ImageView");
		List<PictureMaster> UserPicutres = pictureService.readUserPicture(LoginUser.getUserId());
		

So far we have talked about Java. Let's pass the data obtained here to jsp!

Reading on the jsp side

By the way, the controller and jsp use an object called Model to exchange values. It's a little different from the string.

Now let's use the latest technology. The image registered in the DB is binary data, Convert this to BASE64.

BASE64 is an encoding method for exchanging binary data at high speed on the Web. Replaces data such as ordinary hexadecimal numbers with 64-base character data. It is implemented from Java8, so let's use it.

ImageIOController.java


	@RequestMapping(value = "/imageView", method = RequestMethod.GET)
	public ModelAndView imageView(Principal principal) {
		
		//Get credentials
        Authentication auth = (Authentication)principal;
        LoginUserDetails LoginUser = (LoginUserDetails)auth.getPrincipal();
		
		//Get user registration image
		ModelAndView mv = new ModelAndView("ImageView");
		List<PictureMaster> UserPicutres = pictureService.readUserPicture(LoginUser.getUserId());
		
		for(PictureMaster pict:UserPicutres) {
			//Get extension
			pict.setExtension(pict.getOriginalName().substring(pict.getOriginalName().length() - 4, pict.getOriginalName().length()));
			//Convert to BASE64
			pict.setBase64string(Base64.getEncoder().encodeToString(pict.getPictureData()));
			//Delete binary data
			pict.setPictureData(null);
		}
		
		mv.addObject("UserName",LoginUser.getUsername());
		mv.addObject("UserPictures", UserPicutres);
		
		return mv;
	}

Like this. Please see the comments for the contents of the process.

Let's create the processing on the jsp side.

ImageVire.html


<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<head>
<meta content="ja" http-equiv="Content-Language" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Please enter your favorite sea or water image</title>
</head>

<body>
<p>
${UserName}It is an image registered by Mr. ヾ(¡>﹏<¡)No</p>
<c:forEach var="picture" items="${UserPictures}" varStatus="status">

	<p>${picture.pictureName}</p>
	<img src="data:image/${picture.extension};base64,${picture.base64string}">

</c:forEach>
</body>

</html>


The loop is looped with the usual ** c tag **. The point is the tag here.

Specify the extension with ** $ {picture.extension} **, ** base64, $ {picture.base64string} ** specifies the base64 binary.

In other words, the actual HTML output looks like this.

ImageView.html


<img src="data:image/${picture.extension};base64,${picture.base64string}">

Run

Let's run

image.png

I was able to display the registered image like this.

reference How to embed an image directly in an HTML file with Base64 I want to know how to input an image or file (pdf, etc.) in JSP, register it in the DB, and then call it up and display it on the screen.

Recommended Posts

Implement image input / output with Spring MVC
Just input and output images with Spring MVC
Implement file download with Spring MVC
I tried to implement file upload with Spring MVC
Java Config with Spring MVC
Implement GraphQL with Spring Boot
Implement CRUD with Spring Boot + Thymeleaf + MySQL
Let's write Java file input / output with NIO
Ruby input / output
Try to implement login function with Spring Boot
[Spring] Implement the input form (input screen ⇒ confirmation screen ⇒ completion screen)
Request parameter log output sample Java & Spring MVC
[Implementation procedure] Implement image upload function with Active Storage
Spring Security usage memo: Cooperation with Spring MVC and Boot
Implement a simple Rest API with Spring Security with Spring Boot 2.0
Spring with Kotorin --- 5. Actuator
Self-made Validation with Spring
Spring with Kotorin ―― 1. SPRING INITIALIZR
Download with Spring Boot
Output FizzBuzz with stream
MOCK constructors of other classes with Spring MVC + PowerMock + Junit
Output embedded Tomcat access log to standard output with Spring Boot
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
Flow until output table data to view with Spring Boot
To receive an empty request with Spring Web MVC @RequestBody
Implement REST API with Spring Boot and JPA (domain layer)
Implement a simple Rest API with Spring Security & JWT with Spring Boot 2.0
[Java] I want to test standard input & standard output with JUnit