Basic2,3 . spring とcloudinary

```build.gradle
	implementation 'com.cloudinary:cloudinary-http44:1.26.0'
```

```application.yml
cloudinary:
  cloud_name: name
  api_key: key
  api_secret: xxxx
```

```entity/Photo.java
@Entity(name = "photo")
public class Photo {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Basic
    private String title;

    @Basic
    private String image;

    @Basic
    private Date createdAt = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt =  createdAt;
    }

    public StoredFile getUpload() {
        StoredFile file = new StoredFile();
        file.setPreloadedFile(image);
        return file;
    }

    public void setUpload(StoredFile file) {
        this.image = file.getPreloadedFile();
    }

}
```


```repository/PhotoRepository.java
public interface PhotoRepository extends JpaRepository<Photo, Long> {
}
```


create部分を下記に変更する

```controller/company/CompanyController.java
	@PostMapping
    public String create(@ModelAttribute CompanyForm companyForm) throws IOException {
        Company company = new Company();
        company.setName(companyForm.getName());
        company.setDescription(companyForm.getDescription());
        PhotoUpload photoUpload = new PhotoUpload();
        Map uploadResult = null;
        if (companyForm.getFile() != null && !companyForm.getFile().isEmpty()) {
            uploadResult = Singleton.getCloudinary().uploader().upload(companyForm.getFile().getBytes(),
                    ObjectUtils.asMap("resource_type", "auto"));
            photoUpload.setPublicId((String) uploadResult.get("public_id"));
            Object version = uploadResult.get("version");
            if (version instanceof Integer) {
                photoUpload.setVersion(new Long((Integer) version));    
            } else {
                photoUpload.setVersion((Long) version);
            }
            
            photoUpload.setSignature((String) uploadResult.get("signature"));
            photoUpload.setFormat((String) uploadResult.get("format"));
            photoUpload.setResourceType((String) uploadResult.get("resource_type"));
        }

        Photo photo = new Photo();
        photo.setCompany(company);
        photo.setUpload(photoUpload);

        companyRepository.save(company);
        photoRepository.save(photo);
        return "redirect:/companies";
    }
	
```


```com.example.demo/config/Singleton.java
package com.example.demo.config;

import com.cloudinary.Cloudinary;
import com.cloudinary.utils.ObjectUtils;

import org.springframework.beans.factory.annotation.Value;

public class Singleton {
    @Value("${cloudinary.cloud_name}")
    private static String cloudName;
    
	@Value("${cloudinary.api_key}")
	private static String apiKey;

	@Value("${cloudinary.api_secret}")
	private static String apiSecret;

    private static Cloudinary cloudinary;

    public static void registerCloudinary(Cloudinary cloudinary) {
        Singleton.cloudinary = cloudinary;
    }

    public static void deregisterCloudinary() {
        cloudinary = null;
    }

    private static class DefaultCloudinaryHolder {
        public static final Cloudinary INSTANCE = new Cloudinary(ObjectUtils.asMap(
            "cloud_name", "dgn4wqhf0",
            "api_key", "581724769262485",
            "api_secret", "TL4HExoLeReaHnyJ-j7EfuggqVQ"
        ));
    }
        
    public static Cloudinary getCloudinary() {
        if (cloudinary == null) {
            return DefaultCloudinaryHolder.INSTANCE;
        }
        return cloudinary;
    }
}
```

```com.example.demo/form/CompanyForm.java

package com.example.demo.form;

import org.springframework.web.multipart.MultipartFile;

public class CompanyForm {

    private String name;
	private String description;
    private MultipartFile file;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }

    public CompanyForm() {
    }
	
}
```

```company/new
    <div class="container">
      <h1 th:text="${title}">New Company</h1>


ここと
      <form th:action="@{/companies}" th:method="post" enctype="multipart/form-data"> 

        <div class="form-group">
          <label class="control-label">名前</label>
          <input class="form-control" type="text" name="name" />
        </div>
        <div class="form-group">
          <label class="control-label">説明</label>
          <input class="form-control" type="text" name="description" />
        </div>

ここを追加
        <div class="form-group">
          <label for="file">画像:</label>
          <div class="form-control">
              <input type="file" name="file" id="file" />
          </div>

        </div>
        <button class="btn btn-secondary" type="submit">作成</button>
      </form>
      <div class="pull-right">
        <a class="btn btn-link" href="/companies">一覧画面へ</a>
      </div>
    </div>
```


```resources/tempaltes/company/show.html
   <div class="container">
      <h1 th:text="${title}">Show Player</h1>
      <div th:object="${company}">
        <div>
          <label>ID</label>
          <p th:text="*{id}"></p>
        </div>
        <div>
          <label>名前</label>
          <p th:text="*{name}"></p>
        </div>
        <div>
          <label>説明</label>
          <p th:text="*{description}"></p>
        </div>
        <div>
          <label>画像</label>
          <img th:src="*{getThumbnailUrl()}" />
        </div>
```

```com.example.demo/entity/Company.java

	public String getPhotoUrl() {
		return Singleton.getCloudinary().url().generate(photo.getUpload().getPublicId());
	}

	public String getThumbnailUrl() {
		return Singleton.getCloudinary().url()
			.transformation(
				new Transformation().width(150).height(150).crop("thumb")
			).generate(photo.getUpload().getPublicId());
	}
```