전체 글 102

[MVC 기초] Bean Validation (Spring 기능 적극 활용)

Bean Validation Controller단에서 Validation을 구현하는 것은, 소스코드도 복잡해지고 한 눈에 들어오기 어려워진다. 그래서 Spring에서는 Bean Validation을 사용하도록 권장한다. Bean Validation은 JPA처럼 추상 표준기술이다. 많은 구현체들이 존재하고, 대표적으로 하이버네이트 Validation이 있다. Gradle 설정 implementation 'org.springframework.boot:spring-boot-starter-validation' 을 추가해줘야 한다. jakarta.validation:jakarta.validation-api 그래들이 들어온 모습 객체에 @Max, @NotNull 등을 사용할 때 있는 어노테이션이 여기..

스프링/MVC 2022.05.26

[MVC 기초] 스프링 Form Validation 처리하기 (기존 데이터 유지 + properties로 오류 문자 관리 + Spring Validator 사용)

validation (타임리프 + 스프링부트 ) 검증 페이지 생성하기 방법 1. Model에 Error 담아서 view로 리턴 Controller에서 검증하기 프론트 단 뿐만 아니라 백엔드에서도 검증을 수행해야 한다. 순서 Controller의 Model 객체에 'Error'로 담아 넘긴다. 오류가 발생할 경우, 다시 해당 Page 의 View를 보여준다. 타임리프의 조건문으로, 해당 오류가 나는 부분을 수정하라고 사용자에게 보여준다. 방법 2. 스프링이 제공하는 BindingResult 방법 사용하기 BindingResult란? 검증 오류를 보관하는 객체이다. @ModelAttribute 뒤에 인자로 선언하여서 오류가 발생하면 담아서 사용하면 된다. Model에 담지 않아도 자동으로 View화면에 넘어..

스프링/MVC 2022.05.24

[MVC 기초] 메세지와 국제화 (스프링 부트 + 타임리프를 곁들인)

메세징 html에서 사용될 단어들을 properties 파일에 key=value 로 저장해둔 뒤, 가져다 쓰는 것 국제화 언어별로 메세지를 별도 관리하여 국제화 서비스를 구현하는 것 message properties 파일을 언어별로 관리한다. 어떻게 언어를 감지하여 국가별로 다른 언어를 뿌려주는가? http accept-language 헤더 값을 사용하거나 사용자가 직접 언어를 선택하게 하거나, 쿠키등을 사용하여 처리 감지된 언어별로 다른 properties 파일 관리 messages_en.properties 영어 국가에서 접근하면, 선택하면 동작 item=Item item.id=Item ID item.itemName=Item Name item.price=price item.quantity=quantit..

스프링/MVC 2022.05.20

[Thymeleaf] 기본 문법

thymeleaf-basic ?? // #타임리프 기본 사용법 기본 문법 • 간단한 표현: ㅤ ◦ 변수 표현식: ${...} ㅤ ◦ 선택 변수 표현식: *{...} ㅤ ◦ 메시지 표현식: #{...} ㅤ ◦ 링크 URL 표현식: @{...} ㅤ ◦ 조각 표현식: ~{...} • 리터럴 ㅤ ◦ 텍스트: 'one text', 'Another one!',… ㅤ ◦ 숫자: 0, 34, 3.0, 12.3,… ㅤ ◦ 불린: true, false ㅤ ◦ 널: null ㅤ ◦ 리터럴 토큰: one, sometext, main,… • 문자 연산: ㅤ ◦ 문자 합치기: + ㅤ ◦ 리터럴 대체: |The name is ${name}| • 산술 연산: ㅤ ◦ Binary operators: +, ..

스프링 2022.04.28

[MVC 기초] PRG 패턴 (Post->Redirect->Get) 사용자의 Data 등록폼에서 새로고침시 대처법 + RedirectAttribute 으로 동적 html 생성

item-service PRG 패턴 (Post/Redirect/Get) 페이지에서 Data가 SAVE되고 나서, Redirect를 해주지 않으면, 계속해서 같은 URL을 호출하기 때문에 지속적으로 POST에 SAVE 명령을 호출하여 데이터가 저장될 수 있다. 단순 Form View로 전송 @GetMapping("/add") public String addForm() { return "basic/addForm"; } 새로고침 새로고침은 가장 마지막에 요청한 URL 방식을 그대로 반복한다. (Get이던, Post이던) 나쁜 예 @PostMapping("/add") public String addItemV2(@ModelAttribute("item") Item item, Model model) { itemRep..

스프링/MVC 2022.04.24

[JPA 기초] fetch join시에 XtoMany에서 List Collections들과 join시에 중복 데이터 삭제하는법 (JPQL + distinct)

//==fetch join시에 XtoMany에서 List Collections들과 join시에 중복 데이터 삭제하는법 ==// ex) Order를 불러올 때, orderItems도 join해서 부르면 orderItems의 개수만큼 중복 Order가 불려온다. Order에 연결된 orderItems 개수만큼 중복된 모습 fetch join 나쁜 예 public List findAllWithItem(OrderSearch orderSearch) { return em.createQuery("select o from Order o" + " join fetch o.member m" + " join fetch o.delivery d" + " join fetch o.orderItems oi" + " join fetch..

스프링/JPA 2022.04.05

[JPA 기초] API 사용시 DTO로 변환하는 이유 + 주의사항 (DTO 내부에 Entity객체가 없어야 한다)

API 사용을 할 때 DTO를 만들어서 받는 이유 API 스펙에 맞춰서 @ResponseBody Entitny를 사용하는게 아니라 DTO를 하나 만들어서 해야한다. Entity를 사용하게되면 어디까지 API에서 받고 Binding 되는지, 추가적으로 다른 코드에서 Binding 했는지 모를 수도 있다. (모든 변수가 들어올 가능성이 있으므로) 따라서 DTO에 해당 API를 FIT하게 맞춰서 딱 받는 스펙을 알 수 있다. 외부에 Entity를 보여줘서도 안됨. 받은 Request를 CreateMemberRequest DTO를 바인딩하여 생성, CreateMemberResponse로 전송 @PostMapping("/api/v2/members") public CreateMemberResponse saveMem..

스프링/JPA 2022.04.05

[JPA 기초] OSIV (Transaction 생존 범위에 따른 성능, 대처에 대해)

OSIV Open Session in view : 하이버네이트 Open EntityManager in view : JPA 관례상 OSIV라고 한다. (JPA 가 나중에 나옴) 서버시작때 warn을 주는 모습 2022-02-14 00:12:00.577 WARN 19764 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning..

스프링/JPA 2022.04.05

[JPA 기초] JPA에서 기존 엔티티의 값을 수정하는 방법 (부제 : 왜 em.merge() 사용을 지양해야하는가)

준영속Entity의 경우 (준영속Entity는 em.find를 한 것이 아닌, DB에는 존재하지만 순간적으로 자바에서 객체로만 관리되어져 EntitnyManager 1차캐시에 등록X 객체 > Update할 경우 2가지 방법이 존재한다. 변경 감지를 수동으로 사용하는 법 (영속 Entitny로 등록해줘서 dirtyChecking으로 수정되게 하는 법) 결과적으로 말하자면 merge 사용은 지양해야한다. 변경 감지는 따로 updateMethod를 파서 해당 id로 em.find를 시켜 영속성을 만들어 1차캐시에 저장하고, 이후 그 객체를 변경해주면 이후 tx 커밋시에 자동 등록된다. merge도 이와 비슷한 맥락인데, 1차 캐시에서 찾다가 없으면 db에서 꺼내온다. 여기서 영속성이 생기고, 이후 찾아온 객체..

스프링/JPA 2022.04.05