@Controller → File return
@RestController → Data Return이 필요할때
Error 페이지 이동 X → Alert으로 나타내기 위해 코드 리팩토링 해보기
UserController를 보면 @Controller로써 file(page)만 return 가능하다.하지만 alert을 띄우기 위해선 data를 return 해줘야한다.
@Controller
public class UserController {
@Controller로 인해 Data Return은 불가능한 상태
필요에 따라 File을 return하거나 Data를 return 하기 위해서 새로운 annotation인 @Responsebody를 사용한다.
@Responsebody가 메서드에 사용된 경우 그 메서드만 한해 Data return이 가능하게 된다.
* String과 StringBuilder의 차이
→ String은 SCP(String Constant Pool)에 저장된다.(heap)
String a = "안녕"
a = a + "가"
위 코드 처럼 처음 a = "안녕"이고 이후 "가"를 추가하여 a = "안녕가"가 된다. 이 때, SCP에 "안녕가"라는 String이 새롭게 저장되고 a가 그 값을 가르키게 되면서 기존 a = "안녕"은 더이상 사용되지 않는 데이터가 된다. 이렇게 통신을 할 때, 문자열을 쌓게 되면 메모리 부족현상이 발생된다. 따라서 StringBuilder를 사용하게 되면 그림과 같이 동시 접근을 허용하여 훨씬 적은 메모리를 사용할 수 있다.
* String Buffer : 동시 접근 허용 X
1. 유효성 검사 실패 - 자바스크립트 응답(경고창, 뒤로가기)
① 테스트를 위한 /test/join , /test/login 만들고, 메서드 앞에 @ResponseBody를 붙여 해당 메서드에 한해 data를 return 할수 있게 만들었다.
② Script에 에러의 여부에 따라 이동하는 경로와 에러메시지를 표시하는 코드를 작성
public static String back(String msg) {
StringBuilder sb = new StringBuilder();
sb.append("<script>");
sb.append("alert('"+msg+"');");
sb.append("history.back();");
sb.append("</script>");
return sb.toString();
}
public static String href(String path) {
StringBuilder sb = new StringBuilder();
sb.append("<script>");
sb.append("location.href='"+path+"';");
sb.append("</script>");
return sb.toString();
}
public static String href(String path, String msg) {
StringBuilder sb = new StringBuilder();
sb.append("<script>");
sb.append("alert(' " + msg + " ');");
sb.append("location.href='"+ path +"';");
sb.append("</script>");
return sb.toString();
}
- history.back() 함수는 뒤로가기 함수이다. 이 함수를 활용하면 로그인이나, 회원가입 실패 시 입력한 값을 유지한
상태의 페이지를 클라이언트에게 보여줄 수 있다.
- location.href 함수는 해당 경로로 이동하게 해주는 함수
- String Builder를 사용하여 javascript 구문 안에 위와 같이 코드를 넣어주게 되면 에러페이지 이동이 아닌 alert를
띄우며 페이지를 유지 할 수 있다.
③ UserController Refactoring
- ①번 과 같이 본래 사용되는 메서드에 @ResponseBody annotation을 달아준다.
- 에러 페이지로 이동할 필요가 없기에 변수에서 model을 지우고 해당 코드를 삭제하였다
@PostMapping("/join")
public @ResponseBody String join(@Valid JoinReqDto dto, BindingResult bindingResult, Model model) {
System.out.println("에러사이즈 : " + bindingResult.getFieldErrors().size());
if(bindingResult.hasErrors()) {
Map<String, String> errorMap = new HashMap<>();
for(FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
System.out.println("필드 : " + error.getField());
System.out.println("메시지 : " + error.getDefaultMessage());
}
return Script.back(errorMap.toString());
}
userRepository.save(dto.toEntity());
return Script.href("/loginForm");
}
- 에러 발생 시 HashMap에 담는 코드는 유지한 채, 에러 발생 시 해당 에러 메시지를 alert 해주는 코드를 작성하였다. Script에서 작성한 함수르르 import하여 에러 메시지를 toString 형태로 Return
- 로그인도 동일 적용
@PostMapping("/login")
public @ResponseBody String login(@Valid LoginReqDto dto, BindingResult bindingResult, Model model) {
System.out.println("에러사이즈:" + bindingResult.getFieldErrors().size());
if( bindingResult.hasErrors() ) {
Map<String, String> errorMap = new HashMap<>();
for(FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(), error.getDefaultMessage());
System.out.println("필드:" + error.getField());
System.out.println("메시지:" + error.getDefaultMessage());
}
return Script.back(errorMap.toString());
}
User userEntity = userRepository.mLogin(dto.getUsername(), dto.getPassword());
if(userEntity == null) {
return Script.back("아이디 혹은 비밀번호를 잘못 입력하였습니다. 다시 입력하세요");
}else {
session.setAttribute("principal", userEntity);
return Script.href("/", "로그인 성공");
}
}
userEntity 부분은 로그인 시 아이디 혹은 비밀번호 일치여부에 관한 코드이다.
- 로그인 결과
2. 메인 페이지 생성(UI) - BootStrap 활용
* JSTL 사용
https://mvnrepository.com/artifact/javax.servlet/jstl/1.2
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
# header.jsp에 코드 추가
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- BootStrap Cards
Bootstrap 4 Cards
Bootstrap 4 Cards Cards A card in Bootstrap 4 is a bordered box with some padding around its content. It includes options for headers, footers, content, colors, etc. John Doe Some example text some example text. John Doe is an architect and engineer See Pr
www.w3schools.com
<!-- 카드 글 시작 -->
<div class="card">
<div class="card-body">
<h4 class="card-title">Title 부분입니다.</h4>
<a href="#" class="btn btn-primary">상세보기</a>
</div>
</div>
<br />
<!-- 카드 글 끝 -->
- BootStrap Pagination
Bootstrap 4 Pagination
Bootstrap 4 Pagination Basic Pagination If you have a web site with lots of pages, you may wish to add some sort of pagination to each page. To create a basic pagination, add the .pagination class to an element. Then add the .page-item to each element and
www.w3schools.com
<ul class="pagination">
<li class="page-item disabled"><a class="page-link" href="#">Prev</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
- BootStrap Flex
- d-flex : inline block
- justify-content-center : 수평방향으로 가운데
Bootstrap 4 Flex
Bootstrap 4 Flex Bootstrap 4 Flex Use flex classes to control the layout of Bootstrap 4 components. Flexbox The biggest difference between Bootstrap 3 and Bootstrap 4 is that Bootstrap 4 now uses flexbox, instead of floats, to handle the layout. The Flexib
www.w3schools.com
<ul class="pagination d-flex justify-content-center">
<li class="page-item disabled"><a class="page-link" href="#">Prev</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
* 결과
3. board 만들기 - Foreign key 설정
- @JoinColumn : 외래 키를 매핑 할 때 사용한다. name 속성에는 매핑 할 외래 키 이름을 지정
- @ManyToOne : Many To One - 다대일(N:1)
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id; //PK (자동증가 번호)
private String title; // 아이디
private String content;
@JoinColumn(name = "userId")
@ManyToOne
private User user;
}
"Private User user" → 하나의 데이터가 아닌 객체(Object)로 정보를 담는다. 이렇게 할 경우 따로 view를 만들 필요가 없어지고, Board 테이블과 User 테이블을 Inner Join 하여 테이블이 생성된다.
'Programming > SpringBoot' 카테고리의 다른 글
Spring Boot 7강 - Refactoring ① (0) | 2021.09.19 |
---|---|
Spring Boot 6강 - 로그인, 회원가입 (0) | 2021.09.19 |
Spring Boot 5강 - Json, Thread, DB연결 (2) | 2021.09.18 |
Spring Boot 4강 - Mustache, JSP 연결 (0) | 2021.09.05 |
Spring Boot 3강 - 어노테이션, IOC, DI (0) | 2021.09.05 |