Spring Boot REST接口仅响应JSON格式请求的实现问询
Hey there! Let's figure out how to make your /login/checkAuthorization endpoint only accept JSON payloads. Here are two straightforward, production-ready approaches to add that validation before your business logic runs:
@PostMapping's consumes Attribute (Simplest Way) Spring lets you directly restrict the media types an endpoint accepts using the consumes parameter on @PostMapping. This is the cleanest approach because Spring handles the validation automatically—any request with a Content-Type that isn't application/json will get a 415 Unsupported Media Type response before even reaching your method.
Here's how to update your code:
import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class AuthController { @PostMapping( value = "/login/checkAuthorization", consumes = MediaType.APPLICATION_JSON_VALUE ) public PrivilegeResponse checkAuthorizationAction(@RequestBody PrivilegeModel privilegeObj) { // Your business logic goes here—only JSON requests reach this point return new PrivilegeResponse(); } }
Bonus: This works even if the client sends application/json;charset=utf-8 (with charset specified)—Spring will still recognize it as valid JSON content type.
If you want to return a custom error message or handle invalid requests in a specific way (instead of Spring's default 415 response), you can manually validate the Content-Type header and throw a custom exception, then handle it globally.
Step 1: Add Header Validation to Your Endpoint
Inject HttpServletRequest to access the request headers, then check if Content-Type is JSON:
@PostMapping("/login/checkAuthorization") public PrivilegeResponse checkAuthorizationAction( @RequestBody PrivilegeModel privilegeObj, HttpServletRequest request ) { String contentType = request.getHeader("Content-Type"); // Validate Content-Type starts with application/json if (contentType == null || !contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) { throw new InvalidRequestFormatException("Only JSON payloads are accepted for this endpoint"); } // Your business logic return new PrivilegeResponse(); }
Step 2: Create a Custom Exception
public class InvalidRequestFormatException extends RuntimeException { public InvalidRequestFormatException(String message) { super(message); } }
Step 3: Global Exception Handler for Custom Responses
Use @RestControllerAdvice to catch the exception and return a structured error response:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.HttpMediaTypeNotSupportedException; @RestControllerAdvice public class GlobalErrorHandler { // Handle your custom exception @ExceptionHandler(InvalidRequestFormatException.class) public ResponseEntity<ErrorResponse> handleInvalidFormat(InvalidRequestFormatException ex) { ErrorResponse error = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), ex.getMessage()); return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST); } // Also handle Spring's default media type exception (in case someone bypasses your check) @ExceptionHandler(HttpMediaTypeNotSupportedException.class) public ResponseEntity<ErrorResponse> handleUnsupportedMediaType(HttpMediaTypeNotSupportedException ex) { String message = String.format("Only JSON payloads are allowed. Received: %s", ex.getContentType()); ErrorResponse error = new ErrorResponse(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), message); return new ResponseEntity<>(error, HttpStatus.UNSUPPORTED_MEDIA_TYPE); } } // Error response DTO to send structured JSON errors class ErrorResponse { private int statusCode; private String message; public ErrorResponse(int statusCode, String message) { this.statusCode = statusCode; this.message = message; } // Getters (needed for JSON serialization) public int getStatusCode() { return statusCode; } public String getMessage() { return message; } }
- Always prefer the
consumesattribute first—it's more idiomatic Spring and less code. - Don't try to manually parse the request body to check if it's JSON—
@RequestBodyalready handles that, and invalid JSON will throw aHttpMessageNotReadableExceptionwhich you can also handle globally if needed.
内容的提问来源于stack exchange,提问作者Mr.DevEng

