I am trying to pass variables using post in angular to java spring. The java post function is executed, but all of the parameters are null.
var CreditCard = $resource("http://:host::port/" + context + "/agent/creditCard",
{host: "localhost", port: 8080 },
{getTestPost2: {method:'POST', params:{charge:true, jsonPost:"1234"}}
});
var newCard = new CreditCard({number:'0123'});
newCard.name = "Mike Smith";
newCard.$save();
I checked the my network status shows 200 OK.
Request Payloadview source
{number:0123, name:Mike Smith}
name: "Mike Smith"
number: "0123"
Java
#RequestMapping(
value="/agent/creditCard",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody void getTestPost2(
#PathVariable String clientId,
#RequestParam(value="jsonPost", required=false) String jsonPost,
#RequestParam(value="charge", required=false) boolean charge,
#RequestParam(value="name", required=false) String name,
#RequestParam(value="number", required=false) String number
){
logger.debug("jsonPost " + jsonPost);
logger.debug("name " + name);
logger.debug("charge " + charge);
logger.debug("number " + number);
}
Output:
jsonPost null
name null
charge false
number null
Java
#RequestMapping(
value="/agent/creditCard",
method = RequestMethod.POST,
params = { "jsonPost", "charge", "name", "number"}
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public #ResponseBody void getTestPost2(
#PathVariable String clientId,
#RequestParam(value="jsonPost", required=false) String jsonPost,
#RequestParam(value="charge", required=false) boolean charge,
#RequestParam(value="name", required=false) String name,
#RequestParam(value="number", required=false) String number
){
logger.debug("jsonPost " + jsonPost);
logger.debug("name " + name);
logger.debug("charge " + charge);
logger.debug("number " + number);
}
I add params and ResponseBody, you can try it.
You should write a CreditCard class to use as the parameter type. Annotate it with #RequestBody to let a HttpMessageConverter convert the JSON body to the required object.
#ResponseBody
#RequestMapping(
value="/agent/creditCard",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
public void postCreditCard(#RequestBody CreditCard creditCard) {
// process data...
}
Related
Small question regarding how to get the Spring request mapping (GET mapping, POST mapping...), the path (route) parameter(s) as variable(s). A bit of background, we currently have a use case where we take a route, compute some information, (the Disaster Recovery URL, the test URL, the most available URL, but the question is not here) and respond back. This is just a partial example to have something a bit more concrete in the question.
Query at http://the-main-host.com/firstRoute
We return http://go-to-region-us-west3.com/firstRoute and maybe minutes later, we return http://go-to-region-eu-central.com/firstRoute , but again, this is not the question.
#GetMapping(path = "/{id}/firstRoute", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<String> question(#PathVariable #NotBlank final String id, String url) {
String theUrlEnrichedWithOtherInformation = computeExtraInformationForURL(id, url);
return Mono.just(theUrlEnrichedWithOtherInformation + id + "/firstRoute");
}
With time, we are now at some 300 of those handlers, all with real use cases
#PostMapping(path = "/{id}/twoHundredAndFiveRoute", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<String> question(#PathVariable #NotBlank final String id, String url) {
String theUrlEnrichedWithOtherInformation = computeExtraInformationForURL(id, url);
return Mono.just(theUrlEnrichedWithOtherInformation + id + "/twoHundredAndFiveRoute");
}
#GetMapping(path = "/{id}/twoHundredSixtySevenRoute", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<String> question(#PathVariable #NotBlank final String id, String url) {
String theUrlEnrichedWithOtherInformation = computeExtraInformationForURL(id, url);
return Mono.just(theUrlEnrichedWithOtherInformation + id + "/twoHundredSixtySevenRoute");
}
We managed to make it more maintainable by using the Spring array of the path annotation. This way of doing is a bit nicer, it brought down our two hundred methods down to a single digit. We would like to keep using this way is possible. However, we lose the information what was the path being invoked.
#GetMapping(path = {"/{id}/firstRoute", "/{id}/twoHundredSixtySevenRoute"}, produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<String> question(#PathVariable #NotBlank final String id, String url) {
String theUrlEnrichedWithOtherInformation = computeExtraInformationForURL(id, url);
return Mono.just(theUrlEnrichedWithOtherInformation + id + getThePathThatWasUsedFromTheArrayPlease());
}
Is it possible to get it back, like in this speculative example?
What you need is to access the HttpServletRequest instance. This has a lot of information about http invocation.
Spring allow us an easy way to access to this instance:
#RequestMapping(value = "/report/{objectId}", method = RequestMethod.GET)
public #ResponseBody void generateReport(
#PathVariable("objectId") Long objectId,
HttpServletRequest request) {
}
If you have access to HttpServletRequest, you can get any part of the url:
Example: http://myhost:8080/people?lastname=Fox&age=30
String uri = request.getScheme() + "://" + // "http" + "://
request.getServerName() + // "myhost"
":" + // ":"
request.getServerPort() + // "8080"
request.getRequestURI() + // "/people"
"?" + // "?"
request.getQueryString(); // "lastname=Fox&age=30"
request.getRequestURI() should have the path value that you need.
You can get it from HttpServletRequest - request.getRequestURI(). Either autowire it or use it from method parameter.
I have an interface and an implementation class:
Interface
#RequestMapping(value = CUSTOMER_PATH + "{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON + CHARSET_UTF_8_ENCODING})
Response getCustomerDetails(#PathVariable(CONTACT_ID) String id);
Impl
#Override
public Response getCustomerDetails(String id) {
String methodname = "getCustomerDetails: ";
LOG.info(methodname + "Get Customer Details");
Response response;
System.out.println("******************id: " + id);
if (StringUtils.isEmpty(id)) {
response = Response.status(Status.BAD_REQUEST).entity(MockData.customerDetailsInvalid).build();
LOG.info(methodname + "Returning Customer's Details - Status: Invalid Request");
} else {
response = Response.status(Status.OK).entity(MockData.customerDetails).build();
LOG.info(methodname + "Returning Customer's Details - Status: OK");
}
return response;
}
The path ..../MockDataProvider-war/services/mock/customers/7 returns “invalid request”.
The value for id is printed out as null, even though it should be 7.
Anyone know why id is null?
Reason is #PathVariable(CONTACT_ID)
it should be #PathVariable String id this will work.
Fixed it by changing the Interface from:
Response getCustomerDetails(#PathVariable(CONTACT_ID) String id);
to:
Response getCustomerDetails(String id);
and the Impl from:
public Response getCustomerDetails(String id)
to
public Response getCustomerDetails(#PathVariable(CONTACT_ID) String id)
In Java-Jersey, it is possible to receive a dynamic path to a resource, e.g.
localhost:8080/webservice/this/is/my/dynamic/path
#GET
#Path("{dynamicpath : .+}")
#Produces(MediaType.APPLICATION_JSON)
public String get(#PathParam("dynamicpath") String p_dynamicpath) {
return p_dynamicpath;
}
prints out: this/is/my/dynamic/path
Question: how to do this in Spring MVC?
For multiple items inside your path you can access the dynamic path values like this:
#RequestMapping(value="/**", method = RequestMethod.GET)
public String get(HttpServletRequest request) throws Exception {
String dynPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
System.out.println("Dynamic Path: " + dynPath );
return dynPath;
}
If you know beforehand hoe many levels of path variables you'll have you can code them explicit like
#RequestMapping(value="/{path1}/{path2}/**", method = RequestMethod.GET)
public String get(#PathVariable("path1") String path1,
#PathVariable("path2") String path2,
HttpServletRequest request) throws Exception {
String dynPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
System.out.println("Dynamic Path: " + dynPath );
return dynPath;
}
If you want to see the String returned in your browser, you need to declare the method #ResponseBody as well (so the String you return is the content of your response):
#RequestMapping(value="/**", method = RequestMethod.GET, produces = "text/plain")
#ResponseBody
public String get(HttpServletRequest request) throws Exception {
Hello i'm new in implementing Spring REST Web Service what's the cause of my error.
Here's my code
#RequestMapping(value = "/message/{regID}/name/{name}", method = RequestMethod.GET, headers = "Accept=application/json")
public String getMessage(#PathVariable String regID, #PathVariable String name) {
return "Hello Alvin!" + regID + " " + name;
}
i want to call it using the web browser but i failed to successfully invoke it but when i call single parameter of may another RequestMapping is Successfully completed.. Here is the RequestMapping that i successfully called
#RequestMapping(value = "/country/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
public Country getCountryById(#PathVariable int id) {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
for (Country country : listOfCountries) {
if (country.getId() == id)
return country;
}
return null;
}
Or How can i implement multiple parameter for my RequestMapping..?
The chances are that you're using the InternalResourceViewResolver, in which case the methods that return String will interpret the returned valued as a view name that will be searched inside the locations designated in the view resolver. Your no mapping found probably refers to that the framework can't find a view name that matches what you're returning
As your intention seems to be to return the text only you should simply additional map your method with #ResponseBody which will in turn add your text to response body instead of interpreting it as a view name, so
#ResponseBody
public String getMessage(#PathVariable String regID, #PathVariable String name)
Otherwise, your mapping is just fine
I you have more than one path variables, you need to sepecify the identifier in #PathVariable:
#RequestMapping(value = "/message/{regID}/name/{name}", method = RequestMethod.GET, headers = "Accept=application/json")
public String getMessage(#PathVariable("regID") String regID, #PathVariable("name") String name) {
return "Hello Alvin!" + regID + " " + name;
}
I am developing a project using Spring Boot. I've a controller which accepts GET requests.
Currently I'm accepting requests to the following kind of URLs:
http://localhost:8888/user/data/002
but I want to accept requests using query parameters:
http://localhost:8888/user?data=002
Here's the code of my controller:
#RequestMapping(value="/data/{itemid}", method = RequestMethod.GET)
public #ResponseBody
item getitem(#PathVariable("itemid") String itemid) {
item i = itemDao.findOne(itemid);
String itemname = i.getItemname();
String price = i.getPrice();
return i;
}
Use #RequestParam
#RequestMapping(value="user", method = RequestMethod.GET)
public #ResponseBody Item getItem(#RequestParam("data") String itemid){
Item i = itemDao.findOne(itemid);
String itemName = i.getItemName();
String price = i.getPrice();
return i;
}
While the accepted answer by afraisse is absolutely correct in terms of using #RequestParam, I would further suggest to use an Optional<> as you cannot always ensure the right parameter is used. Also, if you need an Integer or Long just use that data type to avoid casting types later on in the DAO.
#RequestMapping(value="/data", method = RequestMethod.GET)
public #ResponseBody
Item getItem(#RequestParam("itemid") Optional<Integer> itemid) {
if( itemid.isPresent()){
Item i = itemDao.findOne(itemid.get());
return i;
} else ....
}
To accept both #PathVariable and #RequestParam in the same /user endpoint:
#GetMapping(path = {"/user", "/user/{data}"})
public void user(#PathVariable(required=false,name="data") String data,
#RequestParam(required=false) Map<String,String> qparams) {
qparams.forEach((a,b) -> {
System.out.println(String.format("%s -> %s",a,b));
}
if (data != null) {
System.out.println(data);
}
}
Testing with curl:
curl 'http://localhost:8080/user/books'
curl 'http://localhost:8080/user?book=ofdreams&name=nietzsche'
In Spring boot: 2.1.6, you can use like below:
#GetMapping("/orders")
#ApiOperation(value = "retrieve orders", response = OrderResponse.class, responseContainer = "List")
public List<OrderResponse> getOrders(
#RequestParam(value = "creationDateTimeFrom", required = true) String creationDateTimeFrom,
#RequestParam(value = "creationDateTimeTo", required = true) String creationDateTimeTo,
#RequestParam(value = "location_id", required = true) String location_id) {
// TODO...
return response;
#ApiOperation is an annotation that comes from Swagger api, It is used for documenting the apis.
To accept both Path Variable and query Param in the same endpoint:
#RequestMapping(value = "/hello/{name}", method = RequestMethod.POST)
public String sayHi(
#PathVariable("name") String name,
#RequestBody Topic topic,
//#RequestParam(required = false, name = "s") String s,
#RequestParam Map<String, String> req) {
return "Hi "+name +" Topic : "+ topic+" RequestParams : "+req;
}
URL looks like : http://localhost:8080/hello/testUser?city=Pune&Pin=411058&state=Maha
I was interested in this as well and came across some examples on the Spring Boot site.
// get with query string parameters e.g. /system/resource?id="rtze1cd2"&person="sam smith"
// so below the first query parameter id is the variable and name is the variable
// id is shown below as a RequestParam
#GetMapping("/system/resource")
// this is for swagger docs
#ApiOperation(value = "Get the resource identified by id and person")
ResponseEntity<?> getSomeResourceWithParameters(#RequestParam String id, #RequestParam("person") String name) {
InterestingResource resource = getMyInterestingResourc(id, name);
logger.info("Request to get an id of "+id+" with a name of person: "+name);
return new ResponseEntity<Object>(resource, HttpStatus.OK);
}
See here also