
pom.xml 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
templates > new > other > AddUser.html 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
<div>
<input class="username">
</div>
<div>
<input class="password">
</div>
<div>
<input class="name">
</div>
<div>
<input class="email">
</div>
<button>등록</button>
<script>
</script>
</body>
</html>
controller > UserPageController.java(class) 생성
코드를 입력하세요
서버 실행은 main 에서 반드시 실행 할것!!!
post
/api/user/addition
요청 JSON UserAdditionDto -> username, password, name, email
응답 UserAdditionDto (@RestController)
dto > request > UserAdditionDto(class) 생성
package com.web.study.dto.request;
import lombok.Data;
@Data
public class UserAdditionDto {
private String username;
private String password;
private String name;
private String email;
}
controller > UserRestController(class) 생성
package com.web.study.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.web.study.dto.DataResponseDto;
import com.web.study.dto.ResponseDto;
import com.web.study.dto.request.UserAdditionDto;
@RestController
public class UserRestController {
@PostMapping("/api/user/addition")
public ResponseEntity<? extends ResponseDto> addUser(@RequestBody UserAdditionDto userAdditionDto) {
System.out.println("서버 전송 성공");
return ResponseEntity.ok().body(DataResponseDto.of(userAdditionDto));
}
}
메서드 정의: public ResponseEntity<? extends ResponseDto> addUser(@RequestBody UserAdditionDto userAdditionDto)는 UserAdditionDto 타입의 객체를 입력으로 받아 ResponseDto 타입의 ResponseEntity를 반환하는 addUser 메서드를 정의
ResponseEntity는 HTTP 응답과 관련된 정보를 포함
@PostMapping어노테이션: 이 어노테이션은 이 메서드가 HTTP POST 요청을 처리하며, "/api/user/addition" 경로로 매핑. 클라이언트가 이 경로로 POST 요청을 보내면, addUser 메서드가 실행.
@RequestBody어노테이션: 이 어노테이션은 메서드 인자의 UserAdditionDto 객체가 HTTP 요청 본문에서 변환된 것임을 나타냄. JSON 형태의 HTTP 요청 본문이 자동으로 UserAdditionDto 객체로 변환
ResponseEntity 반환: 요청이 처리된 후, ResponseEntity.ok().body(DataResponseDto.of(userAdditionDto))를 통해 HTTP 응답을 생성하고 반환. 여기서는 HTTP 상태 코드를 '200 OK'로 설정하고 응답 본문에 DataResponseDto 객체를 포함시키며, 이 DataResponseDto 객체는 UserAdditionDto 객체를 이용하여 생성.
결과

AddUser.html 수정
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
<div>
<input class="username">
</div>
<div>
<input class="password">
</div>
<div>
<input class="name">
</div>
<div>
<input class="email">
</div>
<button type="button" class="send-button">등록</button>
<script>
window.onload = () => {
addSendButtonEvent();
}
function addSendButtonEvent(){
const sendButton = document.querySelector(".send-button");
sendButton.onclick = () => {
send();
}
}
function send() {
const username = document.querySelector(".username").value;
const password = document.querySelector(".password").value;
const name = document.querySelector(".name").value;
const email = document.querySelector(".email").value;
const userObj = {
username,
password,
name,
email
};
const request ={
type:"post", //method
url: "http://localhost:8080/api/user/addition",
contentType: "application/json", //요청 데이터 타입
data: JSON.stringify(userObj), // 요청 데이터
dataType:"json", // 응답 데이터 타입
// 응답 성공시에 실행될 메서드 정의
success: (response) => {
console.log(response);
},
// 응답 실패시에 실행될 메서드 정의
error: (error) => {
console.log(error);
}
}
$.ajax(request);
}
</script>
</body>
</html>

- AJAX ( Asynchronous JavaScript and XML )는 웹 개발에서 널리 사용되는 기술로 웹 페이지의 일부부만 업데이트할 수 있게 해주는 동시에, 사용자와 상호작용하는 동안 웹 페이지의 전체 로딩이 필요하지 않음, 이로 인해 사용자 경험이 향상되며, 웹 페이지의 응답 속도도 빨라짐
- 웹 페이지에서 서버와 비동기적으로 데이터를 교환하기 위해
JavaScipt를 사용, 이렇게함으로써 웹 페이지가 다시 로드되지 않고도 서버로부터 데이터를 받아올 수 있으며, 이 데이터를 활용해 페이지의 특정 부분을 업데이트할 수 있음- 원래 AJAX는 XML을 데이터 포맷으로 사용하였지만, 현재는
JSON(JavaScipt Object Notation)이 더 널리 사용되고 있음, JSON은 가볍고, 가독성이 높으며, JavaScript와 호환성이 좋음
- HTTP(Hypertext Transfer Protocol)는 웹 상에서 정보를 주고받을 수 있는 프로토콜이며 클라이언트(웹 브라우저)와 서버 간에 요청과 응답을 주고받으면서 웹 페이지의 내용이나 리소스를 제공, HTTP는 평문(암호화되지 않은 데이터) 형태로 정보를 전송하기 때문에, 중간에서 데이터가 가로채거나 조작할 수 있는 위험이 있음
- HTTPS(Hypertext Transfer Protocol Secure)는 HTTP에 보안 레이어를 추가한 프로토콜로, 웹 상에서 정보를 안전하게 주고받을 수 있음, HTTPS는
SSL(Secure Sockets Layer)또는TLS(Transport Layer Security)라는 암호화 기술을 사용하여 클라이언트와 서버 간의 통신을 암호화 함. 이로 인해 중간자 공격(Man-in-the-middle attack)이나 데이터 유출 등의 보안 위험을 줄일 수 있음
💡요약하면, HTTP는 암호화되지 않은 데이터를 전송하는 반면, HTTPS는 암호화 기술을 사용하여 데이터를 안전하게 전송. 따라서 개인정보, 결제 정보 등 민감한 데이터를 다루는 웹 사이트에서는 HTTPS를 사용하는 것이 권장됨.
Stateless: 각 요청은 서버에 저장되는 클라이언트의 상태 정보 없이 독립적으로 처리됨, 이를 통해 서버의 확장성이 향상되며, 각 요청이 필요한 모든 정보를 포함해야함Client-Server Architecture: 클라이언트와 서버는 서로 독립적으로 발전할 수 있는 구조를 가지고 있음. 이로 인해 클라이언트와 서버 간의 의존성이 줄어들고, 각각의 역할이 명확해짐Cacheable: REST API는 캐시를 사용하여 응답을 저정할 수 있음. 이를 통해 클라이언트가 필요할 때 캐시된 데이터를 재사용할 수 있으며, 서버의 부하를 줄이고 성능을 향상시킬 수 있음Layered System: REST 아키텍처는 여러 계층으로 구성될 수 있으며, 각 계층은 독립적으로 관리되고 발전할 수 있음. 이를 통해 유연한 시스템 구조를 구축할 수 있음
- 이러한 특성 덕분에 REST API는 웹 서비스 간의 통신을 간편하고 표준화된 방식으로 제공하며, 다양한 플랫폼과 언어에서 쉽게 사용할 수 있음
UserPageController
package com.web.study.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class UserPageController {
@GetMapping("/page/user/addition")
public String addUser() {
return "AddUser";
}
@GetMapping("/page/user/search")
public String getUser() {
return "FindUser";
}
@GetMapping("/page/users")
public String getUsers() {
return "UserList";
}
}
UserPageController클래스는 사용자 관련 페이지를 처리하는 컨트롤러로서, 다음과 같은 세가지 엔드 포인트를 제공한다.
1. @GetMapping("/page/user/addition") : 사용자 추가 페이지에 대한 요청을 처리, 이 엔드포인트가 호출되면AddUser라는 뷰 이름을 반환하며, 이 뷰는 사용자 추가 페이지를 표시하는데 사용
2. @GetMapping("/page/user/search") : 사용자 검색 페이지에 대한 요청을 처리, 이 엔드포인트가 호출되면FindUser라는 뷰 이름을 반환하며, 이 뷰는 사용자 검색 페이지를 표시하는데 사용
3. @GetMapping("page/users") : 사용자 목록 페이지에 대한 요청을 처리, 이 엔드포인트가 호출되면UserList라는 뷰 이름을 반환하며, 이 뷰는 사용자 목록 페이지를 표시하는데 사용
@Controller어노테이션은 해당 클래스가 Spring MVC(Model-View-Controller) 컨트롤러로 사용되어야 함을 나타냄
@GetMapping어노테이션은 특정 HTTP GET 요청을 해당 메서드에 매핑함을 나타냄. 이러한 방식으로 사용자와 관련된 웹 페이지에 대한 요청을 각 메서드가 처리하고 적절한 뷰를 반환

AddUser.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
<div>
<input class="username" placeholder="username">
</div>
<div>
<input class="password" placeholder="password">
</div>
<div>
<input class="name" placeholder="name">
</div>
<div>
<input class="email" placeholder="email">
</div>
<button type="button" class="send-button">등록</button>
<script>
window.onload = () => {
addSendButtonEvent();
}
function addSendButtonEvent(){
const sendButton = document.querySelector(".send-button");
sendButton.onclick = () => {
send();
}
}
function send() {
const username = document.querySelector(".username").value;
const password = document.querySelector(".password").value;
const name = document.querySelector(".name").value;
const email = document.querySelector(".email").value;
const userObj = {
username,
password,
name,
email
};
const request ={
type:"post", //method
url: "http://localhost:8080/api/user/addition",
contentType: "application/json", //요청 데이터 타입
data: JSON.stringify(userObj), // 요청 데이터
dataType:"json", // 응답 데이터 타입
// 응답 성공시에 실행될 메서드 정의
success: (response) => {
console.log(response);
},
// 응답 실패시에 실행될 메서드 정의
error: (error) => {
console.log(error);
}
}
$.ajax(request);
}
</script>
</body>
</html>
<script src="https://code.jquery.com/jquery-latest.min.js">jQuery 라이브러리를 불러오는 부분
1.HTML : 사용자 입력을 받기 위한 input 요소들과, 이벤트 리스너를 추가할 버튼 요소가 포함
2. JavaScript : 페이지 로드 시 버튼에 이벤트 리스너를 추가하고, 버튼 클릭 시 서버로 데이터를 전송하기 위한AJAX요청을 구성하고 실행
3. 위 코드에서의 주요 기능은send()함수 내의$.ajax(request)를 통해 이루어짐. 이를 통해 서버로 JSON 형태의 사용자 데이터를 전송하고, 서버의 응답을 처리, 이러한 방식을 AJAX를 사용한 클라이언트-서버 통신이라고 부름
UserRestController
package com.web.study.controller;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.web.study.dto.DataResponseDto;
import com.web.study.dto.ErrorResponseDto;
import com.web.study.dto.ResponseDto;
import com.web.study.dto.request.UserAdditionDto;
class UserStore {
public static Map<Integer, UserAdditionDto> userMap = new HashMap<>();
}
@RestController
public class UserRestController {
@PostMapping("/api/user/addition")
public ResponseEntity<? extends ResponseDto> addUser(@RequestBody UserAdditionDto userAdditionDto) {
System.out.println("서버 전송 성공");
Map<Integer, UserAdditionDto> userMap = UserStore.userMap;
int maxKey = 0;
if(!userMap.keySet().isEmpty()) {
maxKey = Collections.max(userMap.keySet());
}
userMap.put(maxKey + 1 , userAdditionDto);
System.out.println(userMap);
return ResponseEntity.ok().body(DataResponseDto.of(userAdditionDto));
}
@GetMapping("/api/user/{id}")
public ResponseEntity<? extends ResponseDto> getUser(@PathVariable int id) {
// userMap에서 id가 해당 id를 가진 객체를 응답
// 만약에 해당 id가 존재하지 않으면 ErrorResponse를 응답으로 준다.
// errorMessage = 존재하지 않는 id입니다.
Map<Integer, UserAdditionDto> userMap = UserStore.userMap;
UserAdditionDto UserAdditionDto = userMap.get(id);
try {
if(UserAdditionDto == null) {
throw new RuntimeException("존재하지 않는 id입니다.");
}
}catch (Exception e) {
return ResponseEntity.badRequest().body(ErrorResponseDto.of(HttpStatus.BAD_REQUEST,e));
}
return ResponseEntity.ok().body(DataResponseDto.of(UserAdditionDto));
}
@GetMapping("/api/users")
public ResponseEntity<? extends ResponseDto> getUsers() {
return ResponseEntity.ok().body(DataResponseDto.of(UserStore.userMap.values()));
}
}
- 해당 코드는 Java로 작성된 Spring Boot 기반의 RESTful API 컨트롤러.
UserRestController클래스는 사용자 관련 API 엔드포인트를 처리하는 컨트롤러로서 세가지 엔드포인트를 제공
- @PostMapping("/api/user/addition") : 사용자 추가 API 엔드 포인트, 클라이언트로부터 전달받은
UserAdditionDto객체를 서버 측의UserStore클래스의userMap에 저장. 저장이 완료되면 저장된 객체를DataResponseDto로 감싸서 클라이언트에게 응답- @GetMapping("api/user/{id})" : 특정 사용자의 정보를 반환하는 API 엔드 포인트, 클라이언트로부터 전달받은
id값을 이용하여UserStore클래스의userMap에서 해당 사용자 정보를 조회, 사용자 정보가 존재하면DataResponseDto로 감싸서 응답하고, 존재하지 않으면ErrorResponseDto를 반환하여 에러 메시지를 전달- @GetMapping("/api/users") : 모든 사용자 정보를 반환하는 API 엔드 포인트,
UserStore클래스의userMap에 저장된 모든 사용자 정보를 가져와DataResponseDto로 감싸서 클라이언트에게 응답
UserStore클래스는userMap이라는 정적HashMap을 포함하며, 이를 통해 사용자 정보를 메모리에 저장하고 관리ResponseEntity는 HTTP 응답을 구성하기 위한 클래스로, 이를 사용하여 클라이언트에게 응답을 전송할 때 응답 본문과 함께 상태 코드를 설정할 수 있음. 이 코드에서는ResponseEntity.ok()와ResponseEntity.badRequest()를 사용하여 상태 코드를 설정
@RestController어노테이션은 해당 클래스가 Spring REST 컨트롤러로 사용되어야 함을 나타냄
@PostMapping, @GetMapping 어노테이션은 각각 HTTP POST 및 GET 요청을 해당 메서드에 매핑함을 나타냄,
→ 이러한 방식으로 사용자와 관련된 API 요청을 각 메서드가 처리하고 적절한 응답을 반환
URL. 즉, 엔드포인트는 API의 각 기능에 대한 경로를 나타내며, 이를 통해 클라이언트와 서버 간 데이터를 교환 할 수 있음. 일반적으로 엔드포인트는 HTTP메서드와 함께 사용되어 CRUD(Create, Read, Update, Delete)작업을 수행
UserAdditionDto
package com.web.study.dto.request;
import lombok.Data;
@Data
public class UserAdditionDto {
private String username;
private String password;
private String name;
private String email;
}
@@@

조회 성공


조회 실패

