타임리프 속성
spring.thymeleaf.prefix= ViewResolver의 접두어, 기본값은 classpath:/templates/
spring.thymeleaf.suffix= ViewResolver의 접미어, 기본값 .html
spring.thymeleaf.encoding= 템플릿의 인코딩, 기본값 UTF-8
spring.thymeleaf.check-template= 렌더링전에 템플릿 유무 확인, 기본값 true
spring.thymeleaf.check-template-location= 템플릿 위치 존재 확인, 기본값 true
spring.thymeleaf.mode= 사용할 타임리프 TemplateMode, 기본값 HTML
spring.thymeleaf.cache= 처리된 템플릿의 캐시 여부, 기본값 true
spring.thymeleaf.template-resolver-order= ViewResolver의 순서, 기본값 1
spring.thymeleaf.view-names= ViewResolver로 처리될 뷰 이름, 쉼표로 구분
spring.thymeleaf.excluded-view-names= 처리내에서 제외할 뷰 이름, 쉼표로 구분
spring.thymeleaf.enabled= 타임리프 활성화 여부, 기본값 true
spring.thymeleaf.enable-spring-el-compiler= SpEl 표현식 편집 여부, 기본값 flase
spring.thymeleaf.servlet.content-type= http응답에 사용될 콘텐츠 타입, 기본값 text/html
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
resoucres/templeate 밑에작성
@GetMapping("/books.html")
public String Mvc_call(Model model){
log.info("호출");
model.addAttribute("books", bookService.findAll());
return "books/list";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
<thead>
<tr>
<th>제목</th>
<th>작가</th>
<th>ISBN</th>
</tr>
</thead>
<tbody>
<tr th:each="book : ${books}">
<td th:text="${book.title}">제목</td>
<td th:text="${book.authors}">작가</td>
<td>
<a th:href="@{/book.html(isbn=${book.isbn})}" href="#" th:text="${book.isbn}">1234567890123</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
@GetMapping(value = "/book.html", params = "isbn")
public String get(@RequestParam("isbn") String isbn, Model model){
bookService.find(isbn).ifPresent(book -> model.addAttribute("book",book));
return "books/details";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Details</title>
</head>
<body>
<div th:if="${book != null}">
<div>
<div th:text="${book.title}">Title</div>
<div th:text="${book.authors}">Authors</div>
<div th:text="${book.isbn}">ISBN</div>
</div>
</div>
<div th:if="${book} == null">
<h1 th:text="'No Book found with ISBN: ' + ${param.isbn}">Not Found</h1>
</div>
</body>
</html>
오류처리 속성
server.error.whitelabel.enabled= 일반 오류 페이지 활성화, 기본값 true
server.error.path= 에러 페이지 경로, 기본값 /error
server.error.include-exception= 모델에 포함될 예외 처리 이름, 기본값 false
server.error.include-stacktrace= 모델에 스택트레이스 포함 여부, 기본값 never
기본오류 모델 속성)
timestamp : 오류가 발생한 시간
status : 상태코드
error : 오류원인
exception : 상위 예외의 클래스 이름(설정된 경우)
message : 예외처리 메시지
errors : BindingResult의 ObjectError(바인딩이나 검증을 사용한 경우)
trace : 예외 스택트레이스(설정된 경우)
path : 예외가 발생한 URL 경로
커스텀 에러관련 사이트 참고)
https://programmer.ink/think/5cdf88c312c44.html
https://namocom.tistory.com/767
https://mkyong.com/spring-boot/spring-rest-error-handling-example/
https://supawer0728.github.io/2019/04/04/spring-error-handling/
https://happyer16.tistory.com/entry/Spring-MVC%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC
URI 작성방법 : https://okky.kr/article/439132
https://luvstudy.tistory.com/74
https://pjh3749.tistory.com/273
https://springboot.tistory.com/33
https://springboot.tistory.com/25
에러코드를 발생하기위한 여러가지 방법이 있지만
저는 @ControllerAdvice 만 실습하겠습니다.
이것외 에러방법은 구글검색을 추천합니다.
기본 에러코드
package com.example.demo.library;
public class BookNotFoundException extends RuntimeException {
private String error;
private String CustomMessage;
private String isbn;
public BookNotFoundException(String error, String customMessage, String isbn) {
super(error+"/"+customMessage+"/"+isbn);
}
}
@GetMapping("/books/{isbn}")
public ResponseEntity<Book> get(@PathVariable("isbn") String isbn){
return bookService.find(isbn).map(ResponseEntity::ok)
.orElseThrow(() -> new BookNotFoundException("error-0010","No Book is found",isbn));
}
결과)
GET http://localhost:8080/books/9780618640157
HTTP/1.1 500
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 04 Feb 2020 16:39:03 GMT
Connection: close
{
"timestamp": "2020-02-04T16:39:03.219+0000",
"status": 500,
"error": "Internal Server Error",
"message": "error-0010/No Book is found/9780618640157",
"path": "/books/9780618640157"
}
Response code: 500; Time: 112ms; Content length: 173 bytes
커스텀 에러코드 도메인
package com.example.demo.library;
public class ApiErrorResponse {
private String error;
private String CustomMessage;
private String detail;
public ApiErrorResponse(String error, String CustomMessage, String detail) {
this.error = error;
this.CustomMessage = CustomMessage;
this.detail = detail;
}
public String getError() {
return error;
}
public String getCustomMessage() {
return CustomMessage;
}
public String getDetail() {
return detail;
}
public void setError(String error) {
this.error = error;
}
public void setCustomMessage(String customMessage) {
CustomMessage = customMessage;
}
public void setDetail(String detail) {
this.detail = detail;
}
}
커스텀 에러 핸들러
package com.example.demo.library;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(BookNotFoundException.class)
public ResponseEntity<ApiErrorResponse> handleException(BookNotFoundException ex) {
ApiErrorResponse response =
new ApiErrorResponse(ex.getError()+"/"+ HttpStatus.NOT_FOUND, ex.getCustomMessage(), ex.getIsbn());
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
}
예외처리 객체
package com.example.demo.library;
public class BookNotFoundException extends RuntimeException {
private String error;
private String CustomMessage;
private String isbn;
public BookNotFoundException(String error, String customMessage, String isbn) {
this.error = error;
this.CustomMessage = customMessage;
this.isbn = isbn;
}
public String getError() {
return error;
}
public String getCustomMessage() {
return CustomMessage;
}
public String getIsbn() {
return isbn;
}
public void setError(String error) {
this.error = error;
}
public void setCustomMessage(String customMessage) {
CustomMessage = customMessage;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}
에러 던지기
@GetMapping("/books/{isbn}")
public ResponseEntity<Book> get(@PathVariable("isbn") String isbn){
return bookService.find(isbn).map(ResponseEntity::ok)
.orElseThrow(() -> new BookNotFoundException("error-0010","No Book is found",isbn));
}
결과)
GET http://localhost:8080/books/9780618640157
HTTP/1.1 404
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 04 Feb 2020 15:46:34 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"error": "error-0010/404 NOT_FOUND",
"detail": "9780618640157",
"customMessage": "No Book is found"
}
Response code: 404; Time: 118ms; Content length: 96 bytes
만약 에러페이지를 띄우고싶다면
template/error 폴더만들고 그 밑에 404.html 등같은것을 만들면된다.
또는 커스텀 에러html을 만들수있다.
package com.example.demo.library;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.time.LocalDateTime;
@Slf4j
@ControllerAdvice
@Controller
public class ApiExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(value = BookNotFoundException.class)
public String handleBaseException(BookNotFoundException ex, Model model){
ApiErrorResponse response =
new ApiErrorResponse(ex.getError()+"/"+HttpStatus.NOT_FOUND, ex.getCustomMessage(), ex.getIsbn(), LocalDateTime.now());
model.addAttribute("res",response);
return "error/bookerror";
}
@ExceptionHandler(value = Exception.class)
public String handleException(Exception e){return e.getMessage();}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
bookerror<br/>
----------------
<div th:object="${res}">
<p th:text="*{error}"></p>
<p th:text="*{CustomMessage}"></p>
<p th:text="*{detail}"></p>
<p th:text="*{Time}"></p>
</div>
----------------
<div th:object="${res}">
<p th:text="|error : *{error}, CustomMessage : *{CustomMessage}, detail : *{detail}, Time : *{Time}|">message.</p>
</div>
</body>
</html>
결과)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | GET http://localhost:8080/books/9780618640157 HTTP/1.1 404 Content-Type: text/html;charset=UTF-8 Content-Language: ko-KR Transfer-Encoding: chunked Date: Tue, 04 Feb 2020 18:42:48 GMT Keep-Alive: timeout=60 Connection: keep-alive <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> bookerror<br/> ---------------- <div> <p>error-0010/404 NOT_FOUND</p> <p>No Book is found</p> <p>9780618640157</p> <p>2020-02-05T03:42:48.706998200</p> </div> ---------------- <div> <p>error : error-0010/404 NOT_FOUND, CustomMessage : No Book is found, detail : 9780618640157, Time : 2020-02-05T03:42:48.706998200</p> </div> </body> </html> Response code: 404; Time: 10ms; Content length: 477 bytes | cs |
'WEB > 스프링 부트 2' 카테고리의 다른 글
Jetty SSL, Http to Https (0) | 2020.02.06 |
---|---|
Spring SSL, Http to Https (0) | 2020.02.05 |
Messages.properties (0) | 2020.02.05 |
스프링 MVC (0) | 2020.02.04 |
책1 (0) | 2020.02.03 |