Fullstack-Study-241204-250625

커리큘럼(12-30/변경)

01. Java
02. git
03. Database 
04. Jsp [Server]

05. HTML,CSS 
07. JS
06. 미니프로젝트-2W

08. SpringFramework , SrpingBoot (v)
09. React JS [Front-end]
10. 중간프로젝트 (1M)
11. Linux 명령어
12. AWS 클라우드
13. DevOps - Docker
14. App - Android
15. 최종프로젝트 (1M)

스프링 부트

타임리프

th:each

    [[${list}]]

    <ul>
        <li th:each="vo:${list}" >
            [[${vo.id}]]
            [[${vo.name}]]
            [[${vo.salary}]]

        </li>
    </ul>

    <!--  두번째 변수는 상태값을 저장해줌  -->
    <ul>
        <li th:each="vo,status :${list}">
            [[${status}]]<br>
            [[${vo}]]
        </li>
    </ul>
<ul>
    <li th:each="vo:${list}" th:if="${vo.salary}>=3005">
        [[${vo}]]
    </li>
</ul>

th:block

<ul>
    <th:block th:each="vo:${list}">
        <li>[[${vo}]]</li>
    </th:block>
</ul>

1. 쿼리스트링 방법

th:href="@{이동주소(key=value,key=value)}"

  • 키워드 검색, 페이지 네이션 정렬방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용
<li th:each="vo:${list}">
    <a th:href="@{/view/result(name=${vo.name})}">[[${vo.name}]]</a>
</li>

2. 쿼리파라미터 방법

th:href="@{이동주소/{key1}/{key2}(key1=value,key2=value)}"

  • ID나 이름 등을 이용해 특정 데이터를 조회할 때 사용
  • Controller에서는 @PathVariable을 이용해 해당 값을 받아서 사용할 수 있음
# html(view)
<li th:each="vo:${list}">
    <a th:href="@{/view/result2/{a}/{b}(a=값,b=값)">[[${vo.name}]]</a>
</li>

# Controller 
@GetMapping("/result2/{address}/{value}")
public String result2(@PathVariable("address") String address,
                      @PathVariable("value") String value){
    System.out.println(address + ", "+value);
    return "view/result";
}

<script th:inline="javascript">

[[${vo}]]

<script th:inline="javascript">
    var item = `[[${vo}]]`;
    var vo = JSON.parse(item);
    console.log(vo.name);
</script>
  • 문자열 자르기 [[${#strings.substring(vo.name,1,2)}]]

  • 날짜 포맷 [[${#temporals.format(vo.hiredate,'yyyy-MM-dd hh시 mm분 ss초')}]]

파트 분리하기 : <th:fragment="조각이름">

파트 가져오기 : <th:replace="~{경로 :: 조각이름}">

# include
<div th:fragment="part1">
    <h3>공통으로 사용할 UI 파트1</h3>
</div>

<div th:fragment="part2">
    <h3>공통으로 사용할 UI 파트2</h3>
</div>

# html(view)
<th:block th:replace="~{/include/layout01 :: part1}">
</th:block>

<th:block th:replace="~{/include/layout01 :: part2}">
</th:block>

전체 가져오기 :<th:replace="~{경로}">

#include
<header>
    <h3>전체 파일 참조하기</h3>
    <nav>
        <ul>
            <li>메뉴</li>
            <li>메뉴</li>
            <li>메뉴</li>
            <li>메뉴</li>
        </ul>
    </nav>
</header>

#html(view)
<th:block th:replace="~{/include/layout02}">
</th:block>
# Layout(동일한 화면)
<!DOCTYPE html>
<th:block th:fragment="함수(item)"> <!--  이부분에서 section부분에 내용을 추가하는 함수 사용  -->
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <header>
            <h3>모든 페이지가 공통으로 사용하는 템플릿 UI</h3>
        </header>

        <section>
            <th:block th:replace="${item}">

            </th:block>
        </section>

        <footer>
            <p>푸터에 대한 내용</p>
        </footer>
    </body>
    </html>
</th:block>

# html(실제 화면)
<!DOCTYPE html>
<th:block th:replace="~{/include/layout03 :: 함수(~{ :: .box})}"> <!--  이부분에서 layout에서 선언한 함수 사용  -->
    <div id="wrap1">
        아이디선택자 #
    </div>

    <div class="box">
        클래스 선택자 .
    </div>
</th:block>
<!-- 이 페이지에서 인식되야 하는 코드 같은 경우 block태그 밖에 선언-->
<script>
    console.log(1);
</script>

유효성검사(Validation)

implementation 'org.springframework.boot:spring-boot-starter-validation'

유효성 어노테이션

어노테이션 설명 대상
@NotNull null을 허용하지 않음 String,Long,Integer등등 전부 검사
@NotEmpty null, 공백 허용하지 않음 String, Map, Array에 검사
@NotBlank null, 공백을 허용하지 않음, 화이트스페이스 허용하지 않음 String만 적용
@Pattern 정규표현식에 맞는 문자열 String
@Email email형식 공백통과
@Size 글자수 지정 min,max로 설정
@NotBlank(message = "이름은 필수입니다")
private String name;

@NotNull(message = "급여는 필수입니다")
private int salary;

@Pattern(regexp = "01[0-9]{1}-[0-9]{4}-[0-9]{4}",message = "휴대폰 >> 번호는 010-xxxx-xxxx유형입니다")
private String phone;>> 

@NotBlank
@Email(message = "이메일 형식이어야 합니다.")
private String email;

유효성검사 적용

  • 컨트롤러에서 데이터를 받을 떄 @ValidBindingResult객체를 사용해 유효성 검사 진행

유효성검사 메서드(BindingResult)

메서드 기능 클래스명
hasErros() 바인딩된 에러가 있다면 true Erros
getFieldErrors() 유효성 검사에 실패한 필드 목록확인 Errors
getField() 유효성 검사에 실패한 변수명확인 FieldErrors
getDefaultMessage() 유효성 검사에 실패한 변수의 에러메시지 확인 FieldErrors
isBindingFailure() 유혀성 검사에 바인딩이 안된경우 false FieldErrors
@PostMapping("/joinForm")
public String joinForm(@Valid ValidVO vo, BindingResult result){
    // 유효성 검사를 진행해서 실패한 목록들을 BindingResult에 담아줌
    if(result.hasErrors()){ // 유효성검사에 실패하면 true
        List<FieldError> list = result.getFieldErrors(); // 실패 목록
        for(FieldError fieldError : list){
            System.out.println(fieldError.getField());
            System.out.println(fieldError.getDefaultMessage());
        }
        System.out.println(result.getAllErrors());
    }
# Controller
public String joinForm(@Valid ValidVO vo, BindingResult result, Model model , RedirectAttributes redirectAttributes){
    // 유효성 검사를 진행해서 실패한 목록들을 BindingResult에 담아줌
    // 1st
    if(result.hasErrors()){ // 유효성검사에 실패하면 true
        List<FieldError> list = result.getFieldErrors(); // 실패 목록
        for(FieldError err : list){
            System.out.println(err.getField());
            System.out.println(err.getDefaultMessage());
            model.addAttribute("valid_"+err.getField(),err.getDefaultMessage());
            redirectAttributes.addFlashAttribute("valid_"+err.getField(),err.getDefaultMessage());
        }
        redirectAttributes.addFlashAttribute("vo",vo);
        return "redirect:/valid/view";
    }

# view
<form action="joinForm" method="post">
    이름:<input type="text" name="name" th:value="${vo!=null?vo.name:''}">
        <span>[[${valid_name}]]</span>
        <br>
    급여:<input type="number" name="salary" th:value="${vo!=null?vo.salary:''}">
        <span>[[${valid_salary}]]</span>
        <br>
    휴대폰:<input type="text" name="phone" th:value="${vo!=null?vo.phone:''}">
        <span>[[${valid_phone}]]</span>
        <br>
    이메일:<input type="text" name="email" th:value="${vo!=null?vo.email:''}">
        <span>[[${valid_email}]]</span>
        <br>
    <input type="submit" value="유효성검사확인하기">
</form>
# Controller
@PostMapping("/joinForm")
public String joinForm(@Valid @ModelAttribute("vo") ValidVO vo, BindingResult result, Model model){
    // 유효성 검사를 진행해서 실패한 목록들을 BindingResult에 담아줌
    // 2nd
    if(result.hasErrors()){
        return "valid/view";
    }
    return "redirect:/valid/result";
}

# view
<form action="joinForm" method="post">
    이름:<input type="text" name="name" th:value="${vo!=null?vo.name:''}">
        <span th:if="${vo!=null}" th:errors="${vo.name}"></span>
        <br>
    급여:<input type="number" name="salary" th:value="${vo!=null?vo.salary:''}">
        <span th:if="${vo!=null}" th:errors="${vo.salary}"></span>
        <br>
    휴대폰:<input type="text" name="phone" th:value="${vo!=null?vo.phone:''}">
        <span th:if="${vo!=null}" th:errors="${vo.phone}"></span>
        <br>
    이메일:<input type="text" name="email" th:value="${vo!=null?vo.email:''}">
        <span th:if="${vo!=null}" th:errors="${vo.email}"></span>
        <br>
    <input type="submit" value="유효성검사확인하기">
</form>
  • th:errors 옵션으로 에러 메세지 출력
  • vo가 Null인 경우 화면이 출력되지 않기 떄문에 th:if로 vo가 null인지 확인