spring rest Handling empty request body (400 Bad Request)
I solved the issue
(the custom exception handler must extend ResponseEntityExceptionHandler
).
My solution follows:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(
HttpMessageNotReadableException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) {
// paste custom hadling here
}
}
For 400 Bad Request not getting proper error message
I just updated the bootstrap.yml with server.error.include-message=always
. It appears from Spring 2.3.0 the default behavior of Spring has changed. We can refer the following link from more details https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#changes-to-the-default-error-pages-content
Java/Spring > Handle Bad Request response for controller method with @RequestBody when no body is sent in request
The solution was to simply put required = false in RequestBody annotation. After that, I could easily add some logic to throw custom exception and handle it in ControllerAdvice.
@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json")
public Resource<User> registerClient(@RequestBody(required = false) User user, HttpServletRequest request){
logger.debug("addClient() requested from {}; registration of user ({})", getClientIp(request), user);
if(user == null){
throw new BadRequestException()
.setErrorCode(ErrorCode.USER_IS_NULL.toString())
.setErrorMessage("Wrong body or no body in reqest");
} (...)
Empty request body gives 400 error
Setting a new byte[0]
will not send any content on the request body. If you set spring MVC logs to TRACE
you should see a message saying Required request body content is missing
as a root cause of your 400 Bad Request
To support your case you should make your @RequestBody
optional
@RequestMapping(method=RequestMethod.PUT, value="/items/{itemname}")
public ResponseEntity<?> updateItem(@PathVariable String itemname, @RequestBody(required = false) byte[] data) {
// code that saves item
}
Spring post method "Required request body is missing"
You have to pass that as JSON in your body, if it's a POST request.
Why do some characters like brackets cause a 400 BAD REQUEST error in a Spring REST endpoint?
You need to encode the URL on the client side.
http://localhost:8083?a=asd[
you should end up with this
http://localhost:8083?a=asd%5B
Clients usually provide a function for URL encoding, please check its documentation. If you are using a client like Postman for testing then you can right click in the address bar and there you have an option to encode the URL.
Some characters like [
are considered allowed but unsafe characters and that's why encoding is needed.
Later edit:
I've tested your code and request and everything works fine. The only change I made was in controller method to return a String instead of a response entity.
@RestController
class Ctrl {
@GetMapping
public String getEmails(
@RequestParam(required = false, name = "a") String a,
@RequestParam(required = false, name = "b") String b,
@RequestParam(required = false, name = "c") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime c,
@RequestParam(required = false, name = "d") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime d,
@RequestParam(name = "e") Integer e,
@RequestParam(name = "f") Integer f
) {
return "";
}
}
curl --location --request GET 'http://localhost:8083?a=&b=%5BHello&c=&d=&e=0&f=1'
You can enable spring debug/trace logging and see what is happening.
400 bad request returned in spring boot even before the request reaches filter
Basically , The problem was Tomcat
was not letting the request through.
This behavior was introduced in Tomcat 7.0.76, 8.0.42 and 8.5.12, to conform RFC 7231.
This enforced check can be revert using the property requestTargetAllow in catalina.properties
to allow forbiden characters:
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
Since I am using embedded tomcat in Intellij and could not edit cataline.properties
directly, I added
-Dtomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
to VM Options
in Run -> Edit Configuration
.
Related Topics
How to Put a Scanner Input into an Array... for Example a Couple of Numbers
Getting Column Names from a JPA Native Query
How to Do a Limit Query in Jpql or Hql
How to View Apache Parquet File in Windows
Jpa: Update Only Specific Fields
Remove Duplicate Values from Hashmap in Java
Java.Sql.Sqlexception: Access Denied for User 'Root'@'Localhost' (Using Password: Yes)
Showing Morning, Afternoon, Evening, Night Message Based on Time in Java
Replace Whitespace in Json Keys
Createprocess Error=2, the System Cannot Find the File Specified
Set Layout Width Percentage of the Total Screen Width
A Jsonobject Text Must Begin With '{' At 1 [Character 2 Line 1] With '{' Error
Retrieving Data from Biometric Fingerprint Attendance Device
Flush/Clear System.In (Stdin) Before Reading
403 Forbidden When I Try to Post to My Spring API
How to Join Results of Multiple Tables in Spring JPA Repository
No String-Argument Constructor/Factory Method to Deserialize from String Value ('')