[Spring Boot2.4.2] JSONの送受信

src/main/resources/templates/test1/index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <p id="p1"></p>
    <p id="p2"></p>
  </body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
		$("#p1").text("");
		$("#p2").text("");
        var json1 = {
			bangou: "1",
			name: "鈴木",
		};
		$.ajax({
		url: "http://localhost:8080/test1/index",
		type: "POST",
		contentType: "application/json",
		data: JSON.stringfy(json1),
		dataType: "json",
		})
		.done(function (data1, textStatus, jqXHR){
			$("#p1").text(jqXHR.status);
			$("#p2").text(JSON.stringify(data1));
		})
		.fail(function (jqXHR, textStatus, errorThrown){
			$("#p1").text(jqXHR.status);
		})
		.always(function() {});
</script>
</html>

Syain.java

package com.example.demo;
import java.io.Serializable;

public class Syain implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private String bangou;
	private String name;
	
	public String getBangou() {
		return bangou;
	}
	public void setBangou(String bangou) {
		this.bangou = bangou;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

MainController.java
L @ResponseBodyはコントローラからの戻り値を返す
L

package com.example.demo;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test1")
public class MainController {
	
	@PostMapping("/index")
	@ResponseBody
    public Syain output1(
    		@RequestBody Syain syain) {
				System.out.println(syain.getBangou());
				System.out.println(syain.getName());
				return syain;
	}
}

2021-02-07 12:07:42.608 INFO 44783 — [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 772 ms
2021-02-07 12:07:42.743 INFO 44783 — [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService ‘applicationTaskExecutor’
2021-02-07 12:07:42.889 INFO 44783 — [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-02-07 12:07:42.919 INFO 44783 — [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ”
2021-02-07 12:07:42.927 INFO 44783 — [ restartedMain] com.example.demo.TestApplication : Started TestApplication in 1.355 seconds (JVM running for 7.09)
2021-02-07 12:08:35.401 INFO 44783 — [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet ‘dispatcherServlet’
2021-02-07 12:08:35.401 INFO 44783 — [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet ‘dispatcherServlet’
2021-02-07 12:08:35.402 INFO 44783 — [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2021-02-07 12:08:37.410 WARN 44783 — [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method ‘GET’ not supported]

うーむ、上手く表示されんな。。

[Spring Boot2.4.2] AOP(アスペクト指向プログラミング)

pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

AOPファイル TestLog.java

package com.example.demo;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TestLog {
	
	@After("within(com.example.demo.MainController)")
	public void write1() {
		System.out.println("ログイン後");
	}
}

@AspectはAOPとして動作
@After, @Before, @Around, @AfterReturning, @AfterThrowing などがある。

MainController.java

package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {
	
	@GetMapping("/test1")
    public String input1() {
        return "test1";
    }
	
	@GetMapping("/test2")
	public String input2(){
        return "test2";
    }
}

Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.
2021-02-07 11:29:27.692 ERROR 43506 — [ restartedMain] o.s.boot.SpringApplication : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘requestMappingHandlerMapping’ defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map ‘test1’ method
com.example.demo.Test1#write1()
to {GET [/test2]}: There is already ‘mainController’ bean method
com.example.demo.MainController#input2() mapped.

ん? 何故だ??

[Spring Boot2.4.2] DI(依存性注入)を理解する

Syain.java (service)
L @ServiceでDIコンテナに登録する

package com.example.demo;
import org.springframework.stereotype.Service;

@Service
public class Syain {
	public String getName() {
		return "tanka";
	}
}

MainController.java
L Autowiredとは、自動的にクラスのプロパティ(setter)や、メンバ変数に値を設定する機能

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {
	@Autowired
	Syain syain;
	
	@GetMapping("/test1")
	public String write1() {
		return syain.getName();
	}
}

ほう、、、

### アプリ起動時にインスタンスを取得する
Syain.java

package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
 L @BeanはSpring起動時に設定の内容を取り込む
public class Syain {
	@Bean
	public String getName() {
		return "sato";
	}
}

TestApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@SpringBootApplication
public class TestApplication {

	public static void main(String[] args) {
		ApplicationContext syain = new AnnotationConfigApplicationContext(Syain.class);
		SpringApplication.run(TestApplication.class, args);
	}

}

@Beanって起動時の設定のことか、豆の印象が強すぎてイマイチ頭に入って来んかった。。

[Spring Boot2.4.2] フォームとエンティティの連携

エンティティとは?
-> relational databaseの表を表す

src/main/resources/templates/test1/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>check</title>
</head>
<body >
<form method="post" action="#" th:action="@{/test1/testform}" th:object="${test1Form}">
<p><input type="text" id="id" name="id" th:field="*{id}"/></p>
<p><input type="text" id="name" name="name" th:field="*{name}"></p>
<p><input type="submit" value="送信ボタン"></p>
</form>
</body>
</html>

フォームクラス: Test1Form.java
L controllerのmodel.addAttribute(“test1Form”, new Test1Form());でvalidationをかけている

package com.example.demo;

public class Test1Form {
	private Integer id;
	private String name;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

エンティティのクラス: Syain.java (社員)
L formのvalidationと同じく、privateで宣言して、geter, setterを書く
L getter, setterは、データを外部から取得するメソッド、あるいはそのデータを外部から変更するメソッド

package com.example.demo;

public class Syain {
	private Integer id;
	private String name;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

MainController.java

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
@RequestMapping("/test1")
public class MainController {
	@Autowired
	private SyainRepository syainRepository;
	
    @GetMapping
    public String disp1(
    		Model model) {
    	model.addAttribute("test1Form", new Test1Form());
        return "test1/index";
    }
    @PostMapping("/testform")
	public String disp2(Test1Form test1Form) {
		    Syain syain = new Syain();
		    syain.setId(test1Form.getId());
		    syain.setName(test1Form.getName());
		    syainRepository.insertSyain(syain);
			return "redirect:/test1/";
		}
}

pom.xml

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

SyainRepository.java

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class SyainRepository {
	private final JdbcTemplate jdbcTemplate;
	
	@Autowired
	public SyainRepository(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	public void insertSyain(Syain syain) {
		jdbcTemplate.update("INSERT INTO syain(id,name) VALUES (?, ?)",
				syain.getId(), syain.getName());
	}
}

Description:

Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

なるほど、何となくわかってきた。

[Spring Boot2.4.2] フォームの値のバリデーション

pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>

src/main/resources/templates/test1/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>submit</title>
</head>
<body >
<form method="post" action="#" th:action="@{/test1/testform}" th:object="${test1Form}">
<p><input type="text" id="id" name="id" th:field="*{id}"/></p>
<div th:if="${#fields.hasErrors('id')}" th:errors="*{id}"></div>

<p><input type="text" id="name" name="name" th:field="*{name}"></p>
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></div>
<p><input type="submit" value="送信ボタン"></p>
</form>
</body>
</html>

MainController.java

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
@RequestMapping("/test1")
public class MainController {
	
    @GetMapping
    public String disp1(
    		Model model) {
    	model.addAttribute("test1Form", new Test1Form());
        return "test1/index";
    }
    @PostMapping("/testform")
	public String disp2(@Validated Test1Form test1Form
			,BindingResult br) {
		        if (br.hasErrors()) {
		        	return "test1/index";
		        }
			return "test1/testform";
		}
}

Test1Form.java

package com.example.demo;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class Test1Form {
	@NotNull(message="必須項目です")
	private Integer id;
	
	@Size(min=3, max=6, message="3文字から6文字で入力して下さい")
	private String name;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

src/main/resources/templates/test1/testform.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>submit</title>
</head>
<body >

<p>OK</p>

</body>
</html>

やべええええええええええええ
SpringBoot面白いかも。

[Spring Boot2.4.2] Thymeleafを使って値を渡す

pomにdependenciesを追加する

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

src/main/resources/templates/test1/testform.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>submit</title>
</head>
<body>
<form method="get" action="testform">
<input type="text" name="text1">
<input type="submit" value="送信ボタン">
</form>
</body>
</html>

com.example.demo/MainController.java
L @RequestParamはリクエストされたパラメータを受け取り、変数str1にsetする
L addAttributeで変数str1をセット

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/test1")
public class MainController {
	
	@GetMapping
	public String input1() {
		return "test1/index";
	}
	
	@GetMapping("testform")
	public String output1(
			@RequestParam(name = "text1") String str1,
			Model model) {
			model.addAttribute("moji1", str1);
			return "test1/testform";
	}
	
}

src/main/resources/templates/test1/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>submit</title>
</head>
<body>
<p th:text="${moji1}"></p>

</body>
</html>

上手くいかないが、何故上手くいかないのかよくわからん。

[Spring Boot2.4.2] プロジェクト作成

Test1.java

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Test1 {
	
	@GetMapping("/test1")
	public String write1() {
		return "Hello World1";
	}
}

RestControllerはメソッドの戻り値を画面に表示する
@GetMappingは@RequestMapping(method=RequestMethod.GET)と同じ意味
Run As -> Spring boot
http://localhost:8080/test1
Hello World1

application.properties

server.port=8756

pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>true</scope>
		</dependency>

spring-boot-devtoolsをtrueにするとファイルを更新した際に、アプリを再起動しなくても更新される。

[Spring Boot2.4.2] postgresのInsert

src/main/java/com.example.demo.dto
Customer.java

package com.example.demo.dto;

import javax.validation.constraints.NotNull;

public class Customer {
	@NotNull
	private String id;
	
	@NotNull
	private String username;
	
	@NotNull
	private String email;
	
	@NotNull
	private String phoneNumber;
	
	@NotNull
	private String postCode;
}

src/main/java/com.example.demo.repository
CustomerMapper.java
L @Mapperアノテーションを作る
L intは件数、insertはcreate処理
L customerは実際にinsertするobject

package com.example.demo.repository;

import com.example.demo.dto.Customer;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface CustomerMapper {
	
	int insert(Customer customer);
}

src/main/java/com.example.demo.repository
CustomerMapper.xml
L mapper namespaceでMapperを宣言
L #{fieldName} でアクセスすることができる、jdbcType= で型を指定する

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.exmaple.demo.repository.CustomerMapper">
	<insert id="insert" parameterType="com.exmaple.demo.dto.Customer">
		INSERT INTO customer VALUES (
			#{id, jdbcType=VARCHAR},
			#{username, jdbcType=VARCHAR},
			#{email, jdbcType=VARCHAR},
			#{phoneNumber, jdbcType=VARCHAR},
			#{postCode, jdbcType=VARCHAR}
		)
	</insert>
</mapper>

src/test/java/com.example.demo.config
DbConfig.java

package com.example.demo.config;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

public class DbConfig {
	
	@Value("${spring.datasource.username}")
	private String username;
	
	@Value("${spring.datasource.password}")
	private String password;
	
	@Value("${spring.datasource.url}")
	private String url;
	
	@Value("${spring.datasource.driverClassName}")
	private String jdbcDriver;
	
	@Bean
	public DataSource dataSource() {
		return new TransactionAwareDataSourceProxy(
				DataSourceBuilder.create()
					.username(this.username)
					.password(this.password)
					.url(this.url)
					.driverClassName(this.jdbcDriver)
					.build());
	}
}

src/test/java/com.example.demo.service
CustomerService.java

import com.example.demo.dto.Customer;

public interface CustomerService {
	
	Customer register(Customer customer);
}

src/test/java/com.example.demo.service.impl

package com.example.demo.service.impl;

import com.example.demo.dto.Customer;
import com.example.demo.repository.CustomerMapper;
import com.example.demo.service.CustomerService;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService {
	
	private CustomerMapper mapper;
	
	public CustomerServiceImpl(CustomerMapper mapper) {
		this.mapper = mapper;
	}
	
	@Override
	public Customer register(Customer customer) {
		
		String formattedEmail = formatEmail(customer.getEmail());
		
		customer.setEmail(formattedEmail);
		
		mapper.insert(customer);
		return customer;
	}
	
	private String formatEmail(String email) {
		String[] separatedEmail = email.split("@");
		return separatedEmail[0] + "@" + separatedEmail[1].toLowerCase();
	}
}

src/test/java/com.example.demo.controller

package com.example.demo.controller;

import com.example.demo.dto.Customer;
import com.example.demo.service.CustomerService;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/customers")
public class CustomerController {
	
	private CustomerService customerService;
	
	public CustomerController(CustomerService customerService) {
		this.customerService = customerService;
	}
	
	@PostMapping
	public Customer post(@Validated @RequestBody Customer customer, Errors errors) {
		
		if (errors.hasErrors()) {
			throw new RuntimeException((Throwable) errors);
		}
		
		return customerService.register(customer);
	}
}

POST man
body -> json

{
    "id": "011",
    "username": "user011",
    "email": "test.user.011@EXAMPLE.com",
    "phoneNumber": "12345678901",
    "postCode": "4567123"
}

なんやろ、上手く動作しないな。全体の流れは何となく理解したが、🤮🤮🤮

org.springframework.validation.BeanPropertyBindingResult cannot be cast to class java.lang.Throwable (org.springframework.validation.BeanPropertyBindingResult is in unnamed module of loader ‘app’

[Spring Boot2.4.2] postgresのCRUDの前準備

Spring Bootのアーキテクチャ

CRUDの処理は、Mapper(Repository)クラスで行なっている。
Spring Initializrで雛形をgenerateする。
DependenciesにValidation, Spring Web, MyBatis, PostgreSQL Driveを追加する。
mybatisとは?
-> カスタムSQL、ストアドプロシージャ、高度なマッピング処理に対応

src/main/resources/application.yml

# Web
server:
  port: 8081
  servlet:
    context-path: /api

postgres/initdb/01_DDL_CREATE_TABLE.sql

CREATE TABLE customer (
	id VARCHAR(10) PRIMARY KEY,
	username VARCHAR(50) NOT NULL,
	email VARCHAR(50) NOT NULL,
	phone_number VARCHAR(11) NOT NULL,
	post_code VARCHAR(7) NOT NULL
);

postgres/initdb/02_DML_INSERT_INIT_DATA.sql

INSERT INTO customer VALUES ('001', 'user001', 'test.user.001@example.com', '12345678901', '1234567');
INSERT INTO customer VALUES ('002', 'user002', 'test.user.002@example.com', '23456789012', '2345671');
INSERT INTO customer VALUES ('003', 'user003', 'test.user.003@example.com', '34567890123', '3456712');
INSERT INTO customer VALUES ('004', 'user004', 'test.user.004@example.com', '45678901234', '4567123');
INSERT INTO customer VALUES ('005', 'user005', 'test.user.005@example.com', '56789012345', '5671234');
INSERT INTO customer VALUES ('006', 'user006', 'test.user.006@example.com', '67890123456', '6712345');
INSERT INTO customer VALUES ('007', 'user007', 'test.user.007@example.com', '78901234567', '7123456');
INSERT INTO customer VALUES ('008', 'user008', 'test.user.008@example.com', '89012345678', '1234567');
INSERT INTO customer VALUES ('009', 'user009', 'test.user.009@example.com', '90123456789', '2345671');
INSERT INTO customer VALUES ('010', 'user010', 'test.user.010@example.com', '01234567890', '3456712');

test=> select * from customer;
id | username | email | phone_number | post_code
—–+———-+—————————+————–+———–
001 | user001 | test.user.001@example.com | 12345678901 | 1234567
002 | user002 | test.user.002@example.com | 23456789012 | 2345671
003 | user003 | test.user.003@example.com | 34567890123 | 3456712
004 | user004 | test.user.004@example.com | 45678901234 | 4567123
005 | user005 | test.user.005@example.com | 56789012345 | 5671234
006 | user006 | test.user.006@example.com | 67890123456 | 6712345
007 | user007 | test.user.007@example.com | 78901234567 | 7123456
008 | user008 | test.user.008@example.com | 89012345678 | 1234567
009 | user009 | test.user.009@example.com | 90123456789 | 2345671
010 | user010 | test.user.010@example.com | 01234567890 | 3456712

application.yml
-> camel caseとsnake caseの命名の差分をMyBatis側で吸収し、適切にテーブル・カラム名とクラス・フィールド名をマッピングする。

# Datasource
spring:
  datasource:
    driverClassName: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/test
    username: root
    password:
    
# MyBatis
mybatis:
  configuration:
    map-underscore-to-camel-case: true

com.example.demo.controllerにCustomerController.javaを作る
CustomerController.java

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
	
	@GetMapping("/hello")
	public String hello() {
		return "Hello World.";
	}
}


ここまでは基礎

build.gradleに依存性を追加

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'
	runtimeOnly 'org.postgresql:postgresql'
	testImplementation 'org.dbunit:dbunit:2.5.3'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

[AWS CloudFront] 使ってみる

ユーザへの配信を行うサーバを「エッジサーバ」といい、CloudFrontドメイン(*.cloudfront.net)のようなCloudFrontドメインへアクセスさせることにより、CloudFrontのエッジサーバを経由した配信が行える。

ユーザがCloudFrontにアクセスすると、最寄りのエッジサーバIPが返される。このIPにアクセスして、高速な配信が受けられる。

# CloudFrontの使い方
### ディストリビューション作成
Create Distribution

origin-domain-pathは適当に、s3の laravel8-test.s3.amazonaws.com にします。

その他の項目はデフォルトのまま。項目だけ一応見ておく。
– Origin Settings
Enable Origin Shield, Origin ID, Restrict Bucket Access, Origin Connection Attempts, Origin Connection Timeout, Origin Custom Headers
– Default Cache Behavior Settings
Path Pattern, Viewer Protocol Policy, Allowed HTTP Methods, Field-level Encryption Config, Cached HTTP Methods, Cache and origin request settings, Cache Policy, Origin Request Policy, Smooth Streaming, Restrict Viewer Access, Compress Objects Automatically, Lambda Function Associations, Enable Real-time Logs
– Distribution Settings
Price Class, AWS WAF Web ACL, Alternate Domain Names(CNAMEs), SSL Certificate, Supported HTTP Versions, Default Root Object, Standard Logging, S3 Bucket for Logs, Log Prefix, Cookie Logging, Enable IPv6, Comment, Distribution State

ファイルパスを叩く
d2*.cloudfront.net/hoge.jpg
-> S3と同じ画像が表示される。

sugeeeeeeeeee
画像はキャッシュされる
-> 更新のない画像で、海外からのアクセスが多い場合に高速化を発揮する
-> 逆に、更新が多い場合は、キャッシュした画像は更新されない

なるほど、根本的な使い方を勘違いしてたかも