I am trying to curl a string payload and I need it to throw an error if it contains certain parameters.
Here is my code:
#RequestMapping(value = "/payload3", method = RequestMethod.POST, produces = {"application/json"})
public String payloader3(#RequestParam Map<String, String> params ) throws IOException{
#NotNull
String type = mockendpoint.Payload3();
return type;
}
You need to change your return type so that you return a ResponseEntity.
In the event of a successful request, you return a HTTP 200, with the required response body:
return ResponseEntity.ok(json);
And in the event your parameter map size is not equal to your desired value, you can return a HTTP 400, with an appropriate error message:
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(badRequestBody);
You can consume the input as a String instead of Map(that you currently have) and do a split on it with your delimeter |. If the returned array size is not 18 then throw an exception?
Related
In the request specification trying to add query params using the Map<String, Object> but after the request spec gets generated any value in th Object is getting converted to String even if the value passed in Int or anything else
public Response postCall(String body, Map<String, Object> queryParams, int id1, int id2) {
RequestSpecification requestSpecification = genericRequestBuilder.getRequestSpecificationObject(); // setting the basepath and portno. and login
// The ids can be send via the queryParams map but in both the cases either in map or individual query, the values are getting converted into String
requestSpecification.queryParams(queryParams);
requestSpecification.queryParam("id1",id1);
requestSpecification.queryParam("id2",id2);
requestSpecification.body(body);
Response response =
requestSpecification.post(uri);
return response;
}
The query parameter changes as noticed in the debug mode:
result = {LinkedHashMap#4245} size = 6
"stringId1" -> "kmpySmUISimoRrJL6NL73w"
"stringId2" -> "YOgB1-WjSKyZWoCkuY7kBA"
"projectIdentifier" -> "1234"
"requestGuid" -> "1594123919225"
"id1" -> "1"
"id2" -> "1"
All the fields are string except the id1 and id2
I gets an error in Spring Boot , It say that I don't send paramSelect but it is false, I send paramSelect.
I send
public filterResult(paramSelect: string, filterDateStart: string, filterDateEnd: string): Observable<any> {
filterDateStart = filterDateStart.replace(/\//g, '-');
filterDateEnd = filterDateEnd.replace(/\//g, '-');
const url = 'http://localhost:8080/filterResult/' + paramSelect + '/' + filterDateStart + '/' + filterDateEnd;
return this.http.get<any>(url);
Html ERROR->
zone.js:2969 GET http://localhost:8080/filterResult/EDU/04-07-2018/05-07-2018 400 ()
In my SpringBoot ->
#RequestMapping(method = RequestMethod.GET, value = "/filterResult/{paramSelect}/{dateStart}/{dateEnd}", produces = MediaType.APPLICATION_JSON_VALUE)
public List filterResult(#RequestParam("paramSelect") String paramSelect , #RequestParam("dateStart") String dateStart , #RequestParam("dateEnd") String dateEnd) {
System.out.println("llego");
List<Parameter> list = pgService.filterResult(paramSelect, dateStart, dateEnd);
return list;
}
I get an error:
Resolved exception caused by Handler execution: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'paramSelect' is not present
You should change to use #PathVariable instead of #RequestParam for path variables:
public List filterResult(#PathVariable("paramSelect") String paramSelect , #PathVariable("dateStart") String dateStart , #PathVariable("dateEnd") String dateEnd) {
I have in front end a form where the user selects the year and one or more months from a list of months. These params will be sent to Controller as Get Method.
Given an URL like this:
..../{year}/{months}/excel/
Where months would be a variable list of the months selected, i.e [01,02,10].
How I receive all parameters in the Controller?
Here's my controller so far:
#RequestMapping(value = "/{year}/{months}/excel/", method = RequestMethod.GET, produces = EXCEL_FORMAT_HEADER)
public #ResponseBody
ModelAndView getRankingByYearExcel(#PathVariable("year") Integer year,
#RequestParam Map<String, Object> months)
{...}
I did it like this and worked, declaring months as array of Strings:
#RequestMapping(value = "/{year}/excel/", method = RequestMethod.GET, produces = EXCEL_FORMAT_HEADER)
public #ResponseBody
ModelAndView getRankingByYearExcel(#PathVariable("year") Integer year,
#RequestParam String[] months)
And in URL sent variable months as array of strings:
../2016/excel/?months=1,3,12
Thanks for guiding me in this direction
I would change the #RequestParam Map<String, Object> months to #RequestParam String months You can then split the months based on comma.
String[] monthsList = months.split(",");
The monthsList array will have all the user selected values.
Here is how you bind all URI template variable to Map and use.
First of all, You need to change #RequesetParam to #PathVariable
example1:
#RequestMapping("{id}/messages/{msgId}")
public String handleRequest4 (#PathVariable Map<String, String> varsMap, Model model) {
model.addAttribute("msg", varsMap.toString());
return "my-page";
}
example2:
#GetMapping("/request4/{name}/{age}/address/{city}/{country}")
#ResponseBody
public String handler(#PathVariable Map<String, String> params) {
StringBuilder builder = new StringBuilder();
builder.append("URL parameters - <br>");
for (Entry<String, String> entry : params.entrySet()) {
builder.append(entry.getKey() + " = " + entry.getValue() + "<br>");
}
return builder.toString();
}
For more information see doc1 or see doc2
I have a method that when I send a String (which is Standard JSON output) to it it parses it and returns the section I want. It works for the most part but if the String has a low value such as 5.8244367E-4 in it it will fail with the error:
com.codesnippets4all.json.exceptions.JSONParsingException: #Key-Heirarchy::root/resultList/result[5]/ #Key::PercentMisses Invalid VALUE_TOKEN...#Position::282
public String parse(String json, String key) {
JsonParserFactory factory = JsonParserFactory.getInstance();
JSONParser parser = factory.newJsonParser();
Map<?, ?> jsonMap = parser.parseJson(json);
String parsed = jsonMap.get("result").toString();
return parsed;
}
Is there any obvious way to get around this or else an alternate approach I can take to get the same result?
Thanks.
My function looks like this:
#PUT
#Path("property/{uuid}/{key}/{value}")
#Produces("application/xml")
public Map<String,ValueEntity> updateProperty(#Context HttpServletRequest request,
#PathParam("key") String key,
#PathParam("value") String value,
#PathParam("uuid") String uuid) throws Exception {
...
}
I have to modify it, so it accepts indefinite(or many) list of key-value pairs from REST call, something like
#Path("property/{uuid}/{key1}/{value1}/{key2}/{value2}/{key3}/{value3}/...")
Is it possible to store them in an array or list, so I do not list dozens of #PathParams and parameters, to avoid this:
#PathParam("key1") String key1,
#PathParam("key2") String key2,
#PathParam("key3") String key3,
Might be a good opportunity to rethink this design. By using /s, we are in a way signifying, with each / that we are trying to locate a different resource. Key/Value pairs (in the context of the URL) are mainly for query parameters or matrix parameters.
If /property/{uuid} is the path to a main resource, and we just want to offer some parameters to the client for accessing this resource, then we could allow matrix parameters or query parameters
Matrix Parameters (in a request url) will look something like
/12345;key1=value1;key2=value2;key3=value3
A resource method to obtain the values might look something like
#GET
#Path("/property/{uuid}")
public Response getMatrix(#PathParam("uuid") PathSegment pathSegment) {
StringBuilder builder = new StringBuilder();
// Get the {uuid} value
System.out.println("Path: " + pathSegment.getPath());
MultivaluedMap matrix = pathSegment.getMatrixParameters();
for (Object key : matrix.keySet()) {
builder.append(key).append(":")
.append(matrix.getFirst(key)).append("\n");
}
return Response.ok(builder.toString()).build();
}
See PathSegment
Query Parameters (in a request url) might look something like
/12345?key1=value1&key2=value2&key3=value3
A resource method to obtain the values might look something like
#GET
#Path("/property/{uuid}")
public Response getQuery(#PathParam("uuid") String uuid,
#Context UriInfo uriInfo) {
MultivaluedMap params = uriInfo.getQueryParameters();
StringBuilder builder = new StringBuilder();
for (Object key : params.keySet()) {
builder.append(key).append(":")
.append(params.getFirst(key)).append("\n");
}
return Response.ok(builder.toString()).build();
}
See UriInfo
The difference is that Matrix parameters can be embedded into path segments, while query parameters must be placed at the end of the URL. You can also notice a little difference in syntax.
Some Resources
Query String (Wikipedia)
When to use query parameters versus matrix parameters?
URL matrix parameters vs. request parameters
UPDATE
Also looking at the PUT in you method signature, it appears you are trying update a resource using the path as the values for which you are trying to update, as I don't see any parameters in your method for an entity body. When PUTting, you should be sending the representation in the the entity body, not as as path segments or parameters.
A workaround:
#Path("/foo/bar/{other: .*}
public Response foo(#PathParam("other") VariableStrings vstrings) {
String[] splitPath = vstrings.getSplitPath();
}
VariableStrings class:
public class VariableStrings {
private String[] splitPath;
public VariableStrings(String unparsedPath) {
splitPath = unparsedPath.split("/");
}
}
Path segment sequence to vararg array in JAX-RS / Jersey?
Another example where you map the optional parameter to a Map:
#GET
# Produces({"application/xml", "application/json", "plain/text"})
# Path("/location/{locationId}{path:.*}")
public Response getLocation(#PathParam("locationId") int locationId, #PathParam("path") String path) {
Map < String, String > params = parsePath(path);
String format = params.get("format");
if ("xml".equals(format)) {
String xml = "<location<</location<<id<</id<" + locationId + "";
return Response.status(200).type("application/xml").entity(xml).build();
} else if ("json".equals(format)) {
String json = "{ 'location' : { 'id' : '" + locationId + "' } }";
return Response.status(200).type("application/json").entity(json).build();
} else {
String text = "Location: id=" + locationId;
return Response.status(200).type("text/plain").entity(text).build();
}
}
private Map < String, String > parsePath(String path) {
if (path.startsWith("/")) {
path = path.substring(1);
}
String[] pathParts = path.split("/");
Map < String, String > pathMap = new HashMap < String, String > ();
for (int i = 0; i < pathParts.length / 2; i++) {
String key = pathParts[2 * i];
String value = pathParts[2 * i + 1];
pathMap.put(key, value);
}
return pathMap;
}