For security reasons, I need to return a 400 error if the URI request length is greater than 1024 characters in length.
Is there a way to test this in Spring Boot?
Currently I have a simple Controller doing validation on the query string and header params
#RestController
#Validated
public class myController {
#RequestMapping(value = "{id}", method = GET)
public SegmentationResponse getSegments(
#PathVariable("id") #Valid #Size(min = 12) String id,
#RequestHeader(value = "X-API-Key", required = true) #ValidAPIKey String apiKeyHeader,
#RequestParam(value = "myParam", required = true) #Valid #Pattern(regexp = MY_REGEX) String myParam) {
// DO Stuff
}
}
Desired
http://localhost:8080/<More than 1024 chars here>
Returns 400 Bad Request
Related
I am generating the swagger docs for my REST API using SpringFox.
I have added an optional parameter to my API now:
#ApiOperation(
value = "Get all cars"
)
#GetMapping(value = "/cars", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseDTO<CarDTO>> getCars(
#RequestParam(defaultValue = "1") Integer page,
#RequestParam(required = false) String status) {
ResponseDTO<CarDTO> response = service.getCars(page, status);
return ResponseEntity.ok(response);
}
How do I highlight in the swagger docs that one is required and the other is optional?
You have the #ApiParam annotation you can use, it has a property required which you can put to true or false depending on your needs
#ApiOperation(
value = "Get all cars"
)
#GetMapping(value = "/cars", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseDTO<CarDTO>> getCars(
#ApiParam(required = true) #RequestParam(defaultValue = "1") Integer page,
#ApiParam(required = false) #RequestParam(required = false) String status) {
ResponseDTO<CarDTO> response = service.getCars(page, status);
return ResponseEntity.ok(response);
}
As you can see in the documentation, it has other properties like
access
allowableValues
allowMultiple
defaultValue
name
value
I have this controller:
#RestController("ThresholdAdapter")
#RequiredArgsConstructor
#Component
public class ThresholdAdapter {
#Autowired
ThresholdQuery thresholdQuery;
#RequestMapping(value = "/jbdj", method = RequestMethod.GET)
public String testaux() {
return "lkajdfladjlksj";
}
#RequestMapping(value = "/threshold/list", method = RequestMethod.GET)
public List<Threshold> listThreshold(#RequestParam(required = false) String categoria, #RequestParam(required = false) String kpi, #RequestParam(required = false) String data, #RequestParam(required = false) String hora) {
return thresholdQuery.listThreshold(categoria, kpi, data, hora);
}
#RequestMapping(value = "/threshold/update", method = RequestMethod.GET)
public Threshold updateThreshold(#RequestParam String kpi, #RequestParam String weekday, #RequestParam String hour, #RequestParam String valor, #RequestParam Boolean status) {
return thresholdQuery.updateThreshold(kpi,weekday,hour,valor,status);
}
}
When I call:
http://localhost:8080/jbdj
It doesn´t work.
It show the 404 Not Found error.
You need to have the annotation for rest controller for your endpoint. Spring create a bean named as "thresholdAdapter". You should not give any name in "RestController" annotation.
#RestController
#RequiredArgsConstructor
#Component("thresholdAdapter")
There was setting for context path.
Thanks a lot.
I need to send a value from an Angularjs front to a springboot Java back-office.
The back is called by many other fronts and services.
Which means I can change The front but I have to make sure that any change on the back must not break it for the other callers.
So Extra headers or Other fields in the request body etc... any change that won't break the other existing calls is what I'm looking for.
An example of some methods signature:
A HTTP GET signature
#Override
#ResponseStatus(code = HttpStatus.OK)
#RequestMapping(value = "/", method = RequestMethod.GET)
public ResponseEntity<List<Something>> getSomething(
#RequestHeader(name = Constants.HEADER.SOME_CODE) final String code,
#RequestHeader(name = Constants.HEADER.COMPANY_ID) final String companyId,
#RequestHeader(name = Constants.HEADER.CLIENT_ID) final String clientId) {
A HTTP POST signature
#Override
#ResponseStatus(code = HttpStatus.OK)
#RequestMapping(value = "/{pathValue}/transactions", method = RequestMethod.POST)
public ResponseEntity<SomeResponse> requestSomething(
#RequestHeader(name = Constants.HEADER.EFS_CODE) final String vode,
#RequestHeader(name = Constants.HEADER.COMPANY_ID) final String companyId,
#RequestHeader(name = "Access-Code", required = false) final String codeAcces,
#RequestHeader(name = Constants.HEADER.CLIENT_ID) final String clientId,
#PathVariable("pathValue") final String pathValue,
#RequestBody #Valid Transact transaction) {
I have the following code:
#PostMapping()
public ResponseEntity<Object> postAccounts(
#RequestHeader(value = "client-id", required = true) String clientId,
#RequestHeader(value = "X-client-Global-Id", required = false) String clientGlobalID,
#RequestHeader(value = "Authorization", required = true) String authorization,
#Valid #RequestBody(required = true) String inputContract, #RequestBody(required = true)String nameInput, #RequestBody(required = true) Boolean state) {
return new ResponseEntity<>(inputContract, HttpStatus.OK);
}
When call this method by postman give me an error.
trace": "org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:217)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)\r\n\tat
You only can send an one RequestBody, if you want send more than one properties in the body. You must create an object
#PostMapping()
public ResponseEntity<Object> postAccounts(
//Other Headers...,
#Valid #RequestBody(required = true) ObjectWithAllFields) {
return new ResponseEntity<>(ObjectWithAllFields, HttpStatus.OK);
}
EDIT 1
And pls send your error trace.
I'm new in Spring Boot and I want to have the same Request Mapping method for JSON and simple request params, for example:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word,
#RequestBody String hereGoesJSON) {
//Do some stuff
}
So, when request goes with params, only #RequestParam will work, in other cases we will use #RequestBody annotation.
localhost:8080/start?url=htts://google.com&word=Luck
Or may bee I'll be able to write method like this, for accepting any params:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestBody String anyParam) {
//Parse this anyParam
}
?
I've not found this trick in spring documentation, so I will appreciate any links to it.
Okay, I've solved the problem :D
All that I just needed was 2 methods with the same mapping and explicitly specify RequestMethod type:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word) throws InterruptedException {
//Do some stuff
}
#RequestMapping(value = "/start", method = RequestMethod.POST, consumes = "application/json")
public String startJsonProcess(#RequestBody String body) {
//Do another stuff with RequestBody
}
UPD: added "consumes = "application/json". It helps dividing simple POST requests and JSON POST requests.