← Назад к вопросам
Как в @RestController получить данные из тела POST запроса
1.0 Junior🔥 241 комментариев
#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Получение данных из тела POST запроса в @RestController
Это одна из самых частых операций в REST API разработке. Рассмотрю различные подходы.
Основной способ: @RequestBody
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// Самый простой способ
@PostMapping
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
User user = userService.createUser(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
// DTO класс
public class CreateUserRequest {
private String email;
private String firstName;
private String lastName;
private String password;
// Getter and Setter
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
При отправке JSON:
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"password": "securePassword123"
}
Spring автоматически десериализует JSON в объект CreateUserRequest.
С валидацией
import jakarta.validation.constraints.*;
public class CreateUserRequest {
@NotBlank(message = "Email не может быть пустым")
@Email(message = "Email должен быть валидным")
private String email;
@NotBlank(message = "Имя не может быть пустым")
@Size(min = 2, max = 50, message = "Имя должно быть от 2 до 50 символов")
private String firstName;
@NotBlank(message = "Фамилия не может быть пустой")
private String lastName;
@NotBlank(message = "Пароль не может быть пустым")
@Size(min = 8, message = "Пароль должен быть минимум 8 символов")
private String password;
// Getters and Setters
}
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody CreateUserRequest request) {
// Если данные невалидны, Spring выбросит BindException
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
Обработка ошибок валидации
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);
ErrorResponse errorResponse = new ErrorResponse(
"Validation failed",
errors,
LocalDateTime.now()
);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
}
}
public class ErrorResponse {
private String message;
private Map<String, String> errors;
private LocalDateTime timestamp;
public ErrorResponse(String message, Map<String, String> errors, LocalDateTime timestamp) {
this.message = message;
this.errors = errors;
this.timestamp = timestamp;
}
// Getters
}
Несколько параметров в одном методе
@PostMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@RequestBody SearchCriteria criteria,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return ResponseEntity.ok(userService.search(criteria, page, size));
}
Получение raw JSON как String
@PostMapping("/raw")
public ResponseEntity<String> processRawJson(
@RequestBody String jsonString) {
// Парсим JSON вручную
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode node = mapper.readTree(jsonString);
String email = node.get("email").asText();
// Обработка
} catch (JsonProcessingException e) {
return ResponseEntity.badRequest().body("Invalid JSON");
}
return ResponseEntity.ok("Processed");
}
Работа с HttpServletRequest напрямую
@PostMapping("/advanced")
public ResponseEntity<Map<String, Object>> processRequest(
HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Получаем input stream
BufferedReader reader = request.getReader();
StringBuilder jsonBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
jsonBuilder.append(line);
}
String jsonString = jsonBuilder.toString();
// Парсим и обрабатываем
return ResponseEntity.ok(Map.of("status", "processed"));
}
Различные типы данных в теле
// XML
@PostMapping(consumes = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<User> createUserXml(@RequestBody User user) {
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
// Form-urlencoded
@PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<User> createUserForm(
@RequestParam String email,
@RequestParam String firstName,
@RequestParam String lastName) {
CreateUserRequest request = new CreateUserRequest();
request.setEmail(email);
request.setFirstName(firstName);
request.setLastName(lastName);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
// Multipart form data (с файлом)
@PostMapping("/with-file")
public ResponseEntity<User> createUserWithFile(
@RequestPart("user") CreateUserRequest userRequest,
@RequestPart("avatar") MultipartFile avatar) throws IOException {
User user = userService.createUser(userRequest);
userService.saveAvatar(user.getId(), avatar);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
Кастомный десериализатор
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
public class CustomUserDeserializer extends JsonDeserializer<CreateUserRequest> {
@Override
public CreateUserRequest deserialize(
JsonParser jp, DeserializationContext ctxt) throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
CreateUserRequest request = new CreateUserRequest();
// Кастомная логика десериализации
String email = node.get("email").asText().toLowerCase();
String firstName = node.get("firstName").asText().trim();
request.setEmail(email);
request.setFirstName(firstName);
request.setLastName(node.get("lastName").asText());
request.setPassword(node.get("password").asText());
return request;
}
}
@JsonDeserialize(using = CustomUserDeserializer.class)
public class CreateUserRequest {
// Fields and methods
}
Testing
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
public void testCreateUser() throws Exception {
String jsonRequest = """
{
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"password": "password123"
}
""";
mockMvc.perform(post("/api/v1/users")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonRequest))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.email").value("user@example.com"));
}
}
Лучшие практики
- Используй DTO классы — не передавай entity напрямую
- Валидируй данные — используй @Valid и Bean Validation
- Обрабатывай ошибки — создай GlobalExceptionHandler
- Документируй API — используй Swagger/OpenAPI
- Логируй значимые события — помогает в отладке
- Используй правильные HTTP статусы — 201 для создания, 400 для ошибок
- Версионируй API — /api/v1/, /api/v2/
Обычно для получения данных из POST запроса достаточно простого подхода с @RequestBody и DTO классом с валидацией.