😵 ~23.11.10

1004 | 파라미터 entity로 보내기, 데이터객체 정의, 파일전송 인코딩과 파일 받아보기

unikue 2023. 10. 4. 14:22

✅ 파라미터를 entity로 한번에 처리하기

파라미터를 객체로 처리할 수 있지만 db와 이름이 불일치할경우 null처리됨

👉 이 부분을 일치시키려면 html에서 name 에 대시(-)를 사용하지않고 낙타표기법으로 바꿔야 한다.

👉 혹은 자바를 활용해서 record를 정의하여 사용할 수 있다 (*클래스는 책임을 부여하기위한 역할자(캡슐화)이므로 데이터를 묶기위한 역할로 레코드가 존재한다)

클래스가 많아지는 경우 유지보수가 어려워질 수 있다. (정의가 많아지면 속성이 바뀔때마다 정의도 체크해야 한다)

 


 

 ✅ 데이터 객체 정의

 

  1. DTO (Data Transfer Object):
    • 데이터 전송 객체로, 주로 서비스 간 데이터 전달에 사용됩니다.
    • 일반적으로 데이터베이스와 관련이 없으며, 비즈니스 로직을 가지고 있지 않습니다.
    • 주로 데이터 전송 시에 데이터를 캡슐화하고, 원격 호출(RPC, REST API 등)을 통해 데이터를 전송할 때 사용됩니다.
  2. VO (Value Object):
    • 값 객체로, 불변(Immutable)하며 비즈니스 로직을 가질 수 있습니다.
    • 주로 도메인 모델 내에서 값을 나타내는 객체로 사용됩니다.
    • 주로 도메인 로직에서 사용되며, 데이터 변경 시 새로운 객체를 생성하는 방식으로 처리됩니다.
  3. Model:
    • MVC 아키텍처에서 화면 표현을 담당하는 객체입니다.
    • 사용자 인터페이스(UI)와 상호 작용하며, UI와 데이터 사이의 통신을 관리합니다.
    • MVC에서 Model은 비즈니스 로직을 나타내기도 하지만, 이것은 일반적인 용어로 사용되는 Model의 의미와 다를 수 있습니다.
  4. 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

✔️ 이미지 등록시 필요한 것

  1. 인코딩 방식 이해
  2. redirection 방식 이해

 

 

#️⃣ 리디렉션:: redirection

forward: 서버단에서 서블릿의 호출관계

redirect: 다시 요청. 다시 요청하는 주체가 클라이언트.  서버에 자료가 등록된 후 클라이언트가 재요청함.

(Post하면 다시 겟요청에게 가서 알아서하라는 것. POST는 접수만 하고 문서만 반환하지 않는다)

 

post전송시 302가 뜬다.

 

 

 

#️⃣ 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은 사람이 읽기 쉽고 쓰기 쉬운 형식을 가지고 있으며, 주로 다음과 같은 목적으로 사용됩니다:

  1. 데이터 직렬화: 데이터를 텍스트 형식으로 표현하여 파일 또는 메시지로 저장하거나 전송할 때 사용됩니다. 특히, 프로그래밍 언어 간에 데이터를 주고받을 때 자주 사용됩니다.
  2. 설정 파일: 설정 정보를 저장하기 위한 구성 파일 형식으로 사용됩니다. 소프트웨어 설정, 구성 파일, 환경 변수 등을 표현하는 데 유용합니다.
  3. 텍스트 마크업: 텍스트 문서 내에서 데이터를 나타내고 구조화할 때 사용됩니다. 예를 들어, 마크다운(Markdown) 문서에서 테이블을 정의하거나 데이터를 표현하는 데에 활용될 수 있습니다.

 

  • 맵컬렉션은 메모리상에서만 키와 값을 저장한다.
  • 만약 키와 값을 파일에 저장하고싶다면 application.properties에 저장한다.
  • properties에 저장해도 되지만 yml을 생성해서 추가 세팅을 할 수 있다.

👉 YAML은 JSON같은 표기법으로 중복되는 패키지 명을 줄일 수 있다 (*하위속성을 탭으로 구분한다)

 

  • 스프링은 application.properties를 먼저 읽고 application.yml을 읽는다.
  • 먼저 설정할 내용은 properties에 넣어도 되고, properties를 비워놓고 yml에 모두 설정해도 됨.
  • 즉 편한 표기법 위주로 사용하면 됨!

 

(좌) 기존 application.properties (우)application.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();