← Назад к вопросам

Как в @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"));
    }
}

Лучшие практики

  1. Используй DTO классы — не передавай entity напрямую
  2. Валидируй данные — используй @Valid и Bean Validation
  3. Обрабатывай ошибки — создай GlobalExceptionHandler
  4. Документируй API — используй Swagger/OpenAPI
  5. Логируй значимые события — помогает в отладке
  6. Используй правильные HTTP статусы — 201 для создания, 400 для ошибок
  7. Версионируй API — /api/v1/, /api/v2/

Обычно для получения данных из POST запроса достаточно простого подхода с @RequestBody и DTO классом с валидацией.