티스토리 뷰
@PathVariable : URL 경로의 일부로 매개변수를 전달
@RequestBody : 요청 본문(body)에 JSON 데이터를 포함하여 전달
@RequestParam : URL의 쿼리 파라미터로 매개변수를 전달
HTTP 메서드
1. GET방식
목적 : 리소스를 조회 (SELECT)
자주 사용하는 어노테이션 : @RequestParam , @PathVariable
데이터 전송 방식 : URL의 쿼리 파라미터 또는 경로 변수
1. GET(SELECT)
1) 파라미터가 없는 단순 SELECT
:: 파라미터가 없는 단순 SELECT 요청은 ResponseEntity<T> 를 사용할 것이다.
@ResponseBody를 확장한 형태로, HTTP 상태 코드와 헤더를 함께 제어할 수 있다.
@ResponseBody는 메서드가 반환하는 객체를 HTTP 응답 본문으로 변환하고, 이를 JSON으로 변환하는 데
사용된다.
- @RequestBody: 클라이언트의 HTTP 요청 본문(body)에 포함된 JSON 데이터를 자바 객체로 변환합니다. 주로 POST, PUT 요청에서 사용됩니다.
- ResponseEntity<T>: 서버의 HTTP 응답을 나타내며, 반환할 데이터와 함께 HTTP 상태 코드, 헤더 등을 설정하여 클라이언트에게 전달합니다.
예제 : 모든 사용자 목록을 가져오기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Info</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>User Info</h1>
<div id="user-info"></div>
<script>
$(document).ready(function() {
var userId = 1; // Example user ID
$.ajax({
url: '/api/user', // Server endpoint to get user info
type: 'GET',
data: { userId: userId }, // Sending data as query parameters
dataType: 'json',
success: function(data) {
console.log('User Info:', data);
$('#user-info').text('Name: ' + data.name + ', Email: ' + data.email);
},
error: function(xhr, status, error) {
console.error('Failed to get user info:', error);
}
});
});
</script>
</body>
</html>
클라이언트 측
클라이언트에서는 GET 요청을 보낼 때, URL에 쿼리 파라미터 형식으로 데이터를 전송한다. (data: { userId: userId })
클라이언트에서 { userId: userId } 는 jQuery가 자동으로 userId = 1 같은 쿼리 문자열로 변환하여 URL에 추가한다.
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/api/user")
public ResponseEntity<User> getUserById(@RequestParam int userId) {
User user = userService.getUserById(userId);
if (user != null) {
return ResponseEntity.ok(user); // 200 OK와 함께 User 객체를 반환
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // 404 Not Found와 함께 null 반환
}
}
}
서버 측
서버에서는 ' api/user ' 엔드포인트로 요청을 받는다.
클라이언트가 전송한 쿼리 파라미터를 @RequestParam으로 받는다.
ResponseEntity<User>는 User 객체와 함께 HTTP 상태 코드를 반환합니다.
ResponseEntity.ok(user)는 200 OK 상태 코드와 함께 User 객체를 반환합니다.
ResponseEntity.status(HttpStatus.NOT_FOUND).body(null)는 404 Not Found 상태 코드와 함께 본문이 없는 응답을 반환합니다.
서버 측의 @RequestBody는 메서드의 반환값을 JSON 형식으로 변환하여 클라이언트로 보낸다
// Service.java
@Autowired
private UserMapper userMapper;
public List<User> getAllUsers() {
return userMapper.selectAllUsers();
}
// Controller
@GetMapping("/users")
public String getAllUsers(Model model) {
List<User> users = userService.getAllUsers();
model.addAttribute("users", users);
return "userList";
}
// JSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<title>User List</title>
</head>
<body>
<h1>User List</h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${users}">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
2) @Pathvariable을 사용한 특정 값을 SELECT
@PathVariable
용도 : URL 경로의 "일부"에서 값을 추출
형태 : URL 경로의 변수 자리에 들어가는 값을 처리
예 : 클라이언트가 http://example.com/api/items/123로 요청하면, @PathVariable은
경로의 id 값을 추출해서 메서드 매개변수에 전달
@RequestMapping("/api")
public class ExampleController {
@GetMapping("/items/{id}")
public ResponseEntity<?> getItem(@PathVariable int id) {
// id 경로 변수를 사용하여 처리
return ResponseEntity.ok("Item ID: " + id); }
}
:: GET , DELETE 는 주로 @PathVariable 을 사용해서 특정 값을 매핑한다.
파라미터가 많으면 @RequestBody를 사용해야하지만, GET, DELETE 는 데이터는 body에 담지 않기 때문에
requestBody는 잘 사용하지 않는 것이 좋음
서버에 데이터를 INSERT , PUT 하는 거면 ajax 요청에 data , content-type을 써주기
JSON 데이터를 전송할 때는 'contentType'을 'application/json'으로 설정해야한다.
서버가 요청 본문에 있는 데이터를 JSON 형식으로 해석하도록 알려준다.
예제 : id를 기반으로 users 테이블에서 특정 사용자의 정보를 조회
// Mapper.xml
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" parameterType="int" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id};
</select>
</mapper>
// Service
@Autowired
private UserMapper userMapper;
public User getUserById(int id) {
return userMapper.selectUserById(id);
}
// Controller
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public String getUserById(@PathVariable("id") int id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "userDetail";
}
// JSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<title>User Detail</title>
</head>
<body>
<h1>User Detail</h1>
<c:if test="${not empty user}">
<p>ID: ${user.id}</p>
<p>Name: ${user.name}</p>
<p>Email: ${user.email}</p>
</c:if>
<c:if test="${empty user}">
<p>User not found.</p>
</c:if>
</body>
</html>
3) @RequestParam 을 사용한 특정 값을 SELECT
@RequestParam
용도 : URL의 쿼리 파라미터에서 값을 추출한다
형태 : '?key=value' 형식으로 전달되는 데이터를 처리한다
예 : 클라이언트가 http://example.com/api/items?category=electronics로 요청하면,
@RequestParam 은 category 파라미터의 값을 추출하여 메서드 매개변수로 전달한다.
// RESTController
@RequestMapping("/api")
public class ExampleController {
@GetMapping("/items")
public ResponseEntity<?> getItems(@RequestParam String category) {
// category 쿼리 파라미터를 사용하여 처리
return ResponseEntity.ok("Category: " + category); }
}
// Client
function getItems() {
var category = document . getElementById( 'categoryInput' ). value;
var url = '/api/items?category=' + category;
$.ajax({
url : url,
type:'GET',
success: function( response ) {
document.getElementById('response').innerText='Success: '+ response; },
error: function(error) {
document.getElementById('response').innerText='Error: '+ error.responseText; }
});
}
예제 :
// Controller
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public String getUserById(@RequestParam("id") int id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "userDetail";
}
}
// JSP
<script>
function getUserDetails() {
var userId = 123; // 서버에 전달할 사용자 ID
var url = '/api/users?id=' + userId;
$.ajax({
url: url,
type: 'GET',
success: function(response) {
console.log('Success:', response);
},
error: function(error) {
console.log('Error:', error);
}
});
}
</script>
2. POST(INSERT)
목적 : 새로운 리소스를 생성(INSERT)
자주 사용하는 어노테이션 : @RequestBody
데이터 전송 방식 : 요청 본문에 JSON 형태의 데이터
특정 값을 INSERT 할 때 사용된다. 컨트롤러에서 HTTP Method 방식을 POST로 작성하고, 클라이언트에서도
요청시 POST 방식으로 해야한다. POST는 값을 Body에 담아서 전송하기 때문에?? 컨트롤러에서는 @RequestBody를 사용
해서 클라이언트의 요청 값을 매핑할 수 있다.
예제 : MyBatis를 사용하여 users 테이블에 새로운 사용자를 추가
REST 컨트롤러와 JavaScript의 AJAX 요청을 통해 JSON 데이터를 처리한다
// Mapper.xml
<mapper namespace="com.example.mapper.UserMapper">
<insert id="insertUser" parameterType="com.example.model.User">
INSERT INTO users (name, email)
VALUES (#{name}, #{email});
</insert>
</mapper>
// Service
@Autowired
private UserMapper userMapper;
public void saveUser(User user) {
userMapper.insertUser(user);
}
// RESTController
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@Autowired
private UserService userService;
@PostMapping
public User createUser(@RequestBody User user) {
userService.saveUser(user);
return user;
}
}
// User.java
package com.example.model;
public class User {
private int id;
private String name;
private String email;
// getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
// JSP + JavaScript(AJAX)
<!DOCTYPE html>
<html>
<head>
<title>Create New User</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
$("#userForm").submit(function(event){
event.preventDefault();
<!-- jQuery를 사용하여 폼의 입력 필드에서 데이터를 가져와 user 객체에 저장 -->
var user = {
name: $("#name").val(),
email: $("#email").val()
};
$.ajax({
url: '/api/users',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(user),
success: function(response) {
alert("User created: " + response.name + " (" + response.email + ")");
$("#name").val('');
$("#email").val('');
},
error: function(xhr, status, error) {
alert("An error occurred: " + xhr.responseText);
}
});
});
});
</script>
</head>
<body>
<h1>Create New User</h1>
<form id="userForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<input type="submit" value="Save">
</form>
</body>
</html>
html 부분에서는 id="userForm" 을 가진 <form> 요소를 사용하고,
사용자의 이름, 이메일을 입력받는 두 개의 <input> 요소가 있다
JavaScript 부분에서는 JQuery를 사용해서 폼 제출 이벤트를 가로채고, 폼 데이터를 수집하여 서버로 AJAX 요청을 보낸다 var user = { name: $("#name").val(), email: $("#email").val() }; 부분에서 jQuery를 사용하여 폼의 입력 필드에서 데이터를 가져와 user 객체에 저장
결과가 데이터 타입이 맞지 않는다고 415에러가 발생.
Ajax 는 기본적으로 form Data 전송이고 content-type이 application/x-www-form-urlencoded;으로 나온다.
그래서 content-type을 application/json 으로 명시해주고 data를 JSON.stringify(param) 형태처럼
감싸줘야함!
<script type="text/javascript">
function test() {
var param = {
'id' : document.getElementById("idds").value,
'pw' : document.getElementById("pwws").value
};
$.ajax({
type : 'POST',
url : '/won/sdfsdf',
contentType : "application/json; charset=utf-8",
data : JSON.stringify(param),
success : function(response) {
alert("CONTROLLER RETURN VALUE : " + response);
},
error : function(e) {
alert("ERROR : " + e.statusText);
}
});
}
</script>
3. PUT(UPDATE)
목적 : 기존 리소스를 업데이트
자주 사용하는 어노테이션 : @RequestBody , @PathVariable
데이터 전송 방식 : 요청 본문(body)에 JSON 형태의 데이터, 경로 변수
PUT도 POST 와 마찬가지로 Http Method type은 컨트롤러와 클라이언트에서 put으로 명시해준다
전송방식이 POST 방식이므로, 데이터가 Request Payload(Body)에 들어간다. Content-type 을 application/json,
data 도 JSON.stringify로 감싸준다
POST랑 거의 유사
예제 : MyBatis를 사용하여 users 테이블의 기존 사용자 데이터를 업데이트
// Mapper.xml
<update id="updateUser" parameterType="com.example.model.User">
UPDATE users
SET name = #{name}, email = #{email}
WHERE id = #{id};
</update>
// Service
@Autowired
private UserMapper userMapper;
public void updateUser(User user) {
userMapper.updateUser(user);
}
// Controller
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@Autowired
private UserService userService;
@PutMapping("/{id}")
public User updateUser(@PathVariable int id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
return user;
}
}
// User.java
package com.example.model;
public class User {
private int id;
private String name;
private String email;
// getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
// JSP + JavaScript (AJAX)
<!DOCTYPE html>
<html>
<head>
<title>Update User</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
$("#userForm").submit(function(event){
// 기본 폼 제출 동작을 막음
event.preventDefault();
// 사용자로부터 입력받은 데이터를 수집
var user = {
id: $("#id").val(),
name: $("#name").val(),
email: $("#email").val()
};
// AJAX 요청을 통해 서버로 데이터 전송
$.ajax({
url: '/api/users/' + user.id, // REST API 엔드포인트
type: 'PUT', // HTTP 메소드
contentType: 'application/json', // 데이터 형식
data: JSON.stringify(user), // JSON 형식으로 데이터 전송
success: function(response) {
// 요청이 성공하면 사용자에게 알림
alert("User updated: " + response.name + " (" + response.email + ")");
},
error: function(xhr, status, error) {
// 요청이 실패하면 사용자에게 알림
alert("An error occurred: " + xhr.responseText);
}
});
});
});
</script>
</head>
<body>
<h1>Update User</h1>
<form id="userForm">
<label for="id">ID:</label>
<input type="text" id="id" name="id" required><br>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br>
<input type="submit" value="Update">
</form>
</body>
</html>
4. DELETE(DELETE)
목적 : 기존 리소스를 삭제
자주 사용하는 어노테이션 : @PathVariable
데이터 전송 방식 : 경로 변수
1번인 GET과 동일한 방식. @PathVariable 어노테이션을 사용하면 된다.
DELETE는 Body에 데이터가 들어가지 않기 때문에 클라이언트에서도 JSON타입으로 데이터를 보내주지 않아도
된다?
근데 GET 과는 다르게 @RequestBody도 되는 듯
예제 : MyBatis를 사용하여 users 테이블에서 사용자를 삭제
// Mapper.xml
<mapper namespace="com.example.mapper.UserMapper">
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id};
</delete>
</mapper>
// Service
@Autowired
private UserMapper userMapper;
public void deleteUser(int id) {
userMapper.deleteUser(id);
}
// Controller
RestController
@RequestMapping("/api/users")
public class UserRestController {
@Autowired
private UserService userService;
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable int id) {
userService.deleteUser(id);
}
}
// JSP + JavaScript (AJAX)
<!DOCTYPE html>
<html>
<head>
<title>Delete User</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
$("#deleteForm").submit(function(event){
// 기본 폼 제출 동작을 막음
event.preventDefault();
// 사용자로부터 입력받은 데이터를 수집
var userId = $("#id").val();
// AJAX 요청을 통해 서버로 데이터 전송
$.ajax({
url: '/api/users/' + userId, // REST API 엔드포인트
type: 'DELETE', // HTTP 메소드
contentType: 'application/json', // 데이터 형식
success: function(response) {
// 요청이 성공하면 사용자에게 알림
alert("User deleted with ID: " + userId);
// 입력 필드 초기화
$("#id").val('');
},
error: function(xhr, status, error) {
// 요청이 실패하면 사용자에게 알림
alert("An error occurred: " + xhr.responseText);
}
});
});
});
</script>
</head>
<body>
<h1>Delete User</h1>
<form id="deleteForm">
<label for="id">User ID:</label>
<input type="text" id="id" name="id" required><br>
<input type="submit" value="Delete">
</form>
</body>
</html>
응답코드 :
200 : 클라이언트 요청 정상수행 (응답에 대한 메시지가 포함)
201 : 리소스 생성 요청에 대한 정상처리
202 : 리소스 생성 요청이 비동기적으로 처리될 때 사용
204 : 클라이언트 요청 정상수행 (응답에 대한 메시지 미포함, 보통 삭제요청에 사용)
400 : 클라이언트 요청이 부적절할 때 사용 (부적절한 이유를 응답 Body에 넣어줘야 함)
401 : 클라이언트가 인증되지 않은 상태에서 보호된 리소스를 요청할 때 사용
403 : 클라이언트가 인증상태와 무관하게 응답하고 싶지 않은 리소스를 요청할 때 사용 (400 사용을 권장)
404 : 클라이언트가 요청한 리소스가 존재하지 않을 때 사용
405 : 클라이언트가 불가능한 메소드를 사용했을 때
출처: https://memostack.tistory.com/180 [memostack:티스토리]