1004 | 파라미터 entity로 보내기, 데이터객체 정의, 파일전송 인코딩과 파일 받아보기
✅ 파라미터를 entity로 한번에 처리하기
👉 이 부분을 일치시키려면 html에서 name 에 대시(-)를 사용하지않고 낙타표기법으로 바꿔야 한다.
👉 혹은 자바를 활용해서 record를 정의하여 사용할 수 있다 (*클래스는 책임을 부여하기위한 역할자(캡슐화)이므로 데이터를 묶기위한 역할로 레코드가 존재한다)
클래스가 많아지는 경우 유지보수가 어려워질 수 있다. (정의가 많아지면 속성이 바뀔때마다 정의도 체크해야 한다)
✅ 데이터 객체 정의
- DTO (Data Transfer Object):
- 데이터 전송 객체로, 주로 서비스 간 데이터 전달에 사용됩니다.
- 일반적으로 데이터베이스와 관련이 없으며, 비즈니스 로직을 가지고 있지 않습니다.
- 주로 데이터 전송 시에 데이터를 캡슐화하고, 원격 호출(RPC, REST API 등)을 통해 데이터를 전송할 때 사용됩니다.
- VO (Value Object):
- 값 객체로, 불변(Immutable)하며 비즈니스 로직을 가질 수 있습니다.
- 주로 도메인 모델 내에서 값을 나타내는 객체로 사용됩니다.
- 주로 도메인 로직에서 사용되며, 데이터 변경 시 새로운 객체를 생성하는 방식으로 처리됩니다.
- Model:
- MVC 아키텍처에서 화면 표현을 담당하는 객체입니다.
- 사용자 인터페이스(UI)와 상호 작용하며, UI와 데이터 사이의 통신을 관리합니다.
- MVC에서 Model은 비즈니스 로직을 나타내기도 하지만, 이것은 일반적인 용어로 사용되는 Model의 의미와 다를 수 있습니다.
- Entity:
- 데이터베이스 내에서 테이블을 나타내는 객체입니다.
- 주로 데이터베이스와의 상호 작용 및 영속성(데이터의 지속성)을 다룹니다.
- 데이터베이스 레코드와 매핑되는 객체로, 데이터베이스 스키마와 밀접한 관련이 있습니다.
이들은 개념적으로 다르며, 사용되는 맥락과 목적에 따라 다르게 사용됩니다. DTO와 VO는 데이터 전송 및 도메인 로직에서 사용되며 불변성을 가질 수 있습니다. Model은 사용자 인터페이스 관련 작업에 사용되며 비즈니스 로직도 포함할 수 있습니다. Entity는 데이터베이스와 연관된 영속성과 관련이 깊으며 데이터베이스 테이블과 매핑됩니다.
dto (data transfer object) |
클라이언트 사이드 렌더링시 값을 전달하는 역할 컨트롤러와 클라이언트 사이를 오가는 데이터 객체 |
vo (value object) |
값을 저장하는 것. (model, entity, dto를 모두 아우러서 말하는 개념) |
model | 컨트롤러와 view가 주고받는 객체 정의하는게 아님! 그 자체로 출력할 데이터를 전달한다 |
entity | db와 데이터베이스를 주고받을때 사용 데이터베이스/뷰가 사용하고있는 기본적인 테이블 데이터. (*추가적인 집계값은 scalar) |
- 클라이언트가 필요한 데이터를 한번에 다 주세요 == 모델
- 화면에 필요한 데이터만 주세요 == 엔티티
한번에 데이터를 담아서 가져오려 할 수록 중첩관계가 복잡해지고 서버에 부담이 간다.
dto든 model이든 정의하지말고 임시 구조로 사용하기. (여러번으로 나누어서 객체를 여러번 전달하기)
dto를 다시 entity로 정의하기 X 패키지만들때 dto나 model을 만들 필요가 없다
ex) 1차 댓글 리스트를 가져오고, 클릭한 값에 대해서만 2차 대댓글을 조회해온다. 처음부터 댓글과 대댓글을 모두 들고오지 않음.
✅ 데이터 submit
✔️ 이미지 등록시 필요한 것
- 인코딩 방식 이해
- redirection 방식 이해
#️⃣ 리디렉션:: redirection
forward: 서버단에서 서블릿의 호출관계
redirect: 다시 요청. 다시 요청하는 주체가 클라이언트. 서버에 자료가 등록된 후 클라이언트가 재요청함.
(Post하면 다시 겟요청에게 가서 알아서하라는 것. POST는 접수만 하고 문서만 반환하지 않는다)
#️⃣ multipart 인코딩방식
👉 파일의 경우 인코딩방식이 일반 String과 다르다. 바이너리 방식과 바이너리값을 모두 전송시켜야 함.
👉 form태그에서 enctype="multipart/form-data"로 설정해준다.
- application/x-www-form-urlencoded: 설정하지않으면 세팅되는 기본값. 일반적인 String url (파일은 불가)
- multipart/form-data : 다양한 종류의 데이터를 보낼 수 있도록 문자열, 바이너리, 숫자 등을 모두 파트로 나눠서 보냄
👉 클라이언트에서 multipart로 보냈으므로 서버에서는 multipart로 받는다는 설정을 해야한다.
(*스프링 최신버전에선 자동으로 세팅되긴 한다.)
<form action="reg" method="post" enctype="multipart/form-data"> --- multipart로 인코딩 설정
<fieldset>
<legend>메뉴정보</legend>
<label>이미지<input type="file" class="d:none" name="img-file"></label> -- 이미지 name설정
<label>카테고리</label>
<select>
<option>커피</option>
<option>수제청</option>
<option>쿠키</option>
</select>
@PostMapping("reg")
public String reg(
@RequestParam ("img-file") MultipartFile imgFile, --multipart로 받아주기
@RequestParam(name = "kor-name") String korName,
@RequestParam(name = "eng-name", required = true) String engName,
@RequestParam(defaultValue = "0") int price)
{
Menu menu = Menu.builder()
.korName(korName)
.engName(engName)
.price(price)
.img("imgimg.jpg")
.hit(200)
.memberId(1L)
.build();
service.add(menu);
System.out.println(imgFile.isEmpty()); //값이 없으면 true반환
System.out.println(imgFile.getOriginalFilename()); // file name반환
return "redirect:list";
}
}
#️⃣ 파일 사이즈 제한하기 (+ YAML 활용하기)
YAML - 나무위키
일반적으로 설정파일로 사용하기에 더할 나위없이 좋은 형식이기 때문에 여러 프레임워크나 CI툴에서 설정파일로 쓰이고 있다. Flutter: dart패키지를 관리하기 위해 pubspec.yaml에 설정을 저장한다.d
namu.wiki
YAML(야믈 또는 어물)은 "YAML Ain't Markup Language" 또는 "YAML Ain't a Markup Language"의 약자로서, 데이터 직렬화 및 설정 파일 형식으로 사용되는 경량 마크업 언어입니다. YAML은 사람이 읽기 쉽고 쓰기 쉬운 형식을 가지고 있으며, 주로 다음과 같은 목적으로 사용됩니다:
- 데이터 직렬화: 데이터를 텍스트 형식으로 표현하여 파일 또는 메시지로 저장하거나 전송할 때 사용됩니다. 특히, 프로그래밍 언어 간에 데이터를 주고받을 때 자주 사용됩니다.
- 설정 파일: 설정 정보를 저장하기 위한 구성 파일 형식으로 사용됩니다. 소프트웨어 설정, 구성 파일, 환경 변수 등을 표현하는 데 유용합니다.
- 텍스트 마크업: 텍스트 문서 내에서 데이터를 나타내고 구조화할 때 사용됩니다. 예를 들어, 마크다운(Markdown) 문서에서 테이블을 정의하거나 데이터를 표현하는 데에 활용될 수 있습니다.
- 맵컬렉션은 메모리상에서만 키와 값을 저장한다.
- 만약 키와 값을 파일에 저장하고싶다면 application.properties에 저장한다.
- properties에 저장해도 되지만 yml을 생성해서 추가 세팅을 할 수 있다.
👉 YAML은 JSON같은 표기법으로 중복되는 패키지 명을 줄일 수 있다 (*하위속성을 탭으로 구분한다)
- 스프링은 application.properties를 먼저 읽고 application.yml을 읽는다.
- 먼저 설정할 내용은 properties에 넣어도 되고, properties를 비워놓고 yml에 모두 설정해도 됨.
- 즉 편한 표기법 위주로 사용하면 됨!
mybatis:
configuration:
map-underscore-to-camel-case: true
mapper-locations: mappers/*Mapper.xml
type-aliases-package: kr.co.rland.web.entity
spring:
servlet:
multipart:
max-file-size: 300MB #각 파일의 최대 값
max-request-size: 600MB #요청당 최대 값
#️⃣클라이언트에서 전송한 파일을 받아보기
InputStream fis = imgFile.getInputStream(); //imgFile을 스트림으로 읽어들인다
OutputStream fos = new FileOutputStream("E:\\"+imgFile.getOriginalFilename()); //out할 위치 지정
int size=0;
byte[] buf = new byte[1024]; //1kb크기의 바이트배열 버퍼를 생성
while((size=fis.read(buf))!=-1) // -1를 반환하지 않는이상 write함
fos.write(buf,0,size); //buf를 시작위치 0부터 size만큼 기록
fis.close();
fos.close();