in the below example, i am using POST and GET methods. post is to initialize a varibale and GET is to get this varibale.
I use Postman to make the requests.
i am receiving an error
#RequestBody(value = "val") //cant resolve method value
please let me know how to fix the belwo error so i can use post method for initialization and get methdo to retrieve the value
Controller1
#Controller
#RequestMapping("/call1")
public class Call1 {
public String str = "inti";
#RequestMapping(value = "/intiparam1", method = RequestMethod.POST)
public void intiParam1(#RequestBody(value = "val") String val) {
this.str = val;
}
#RequestMapping(value = "/getparam1", method = RequestMethod.GET)
public String getParam1() {
return this.str;
}
}
Create a class Variable and use other code in controller.
class Variable {
String data= 'val';
}
#RequestMapping(value = "/intiparam1", method = RequestMethod.POST)
public void intiParam1(#RequestBody Variable val) {
this.str = val.data;
}
When making a request pass json as {"data":"12345"}
and then use #RequestBody Variable v in code instead of String as it will serve your purpose of default value and will make the code extensible as you can add different properties to the existing variable in future if needed.
When to use #RequestBody?
You can not use value with it. You can use this when you have multiple field entity which you want to perform the operation. Let's say you want to save the user then you may need to create User Model first and use in a controller #RequestBody.
Model:
public class User
{
#Id
private int id;
private String firstname;
private String lastname;
//Getters-Setters, AllArgConstructor-constructor
}
#RequestMapping(value = "/requestBodyExample", method = RequestMethod.POST)
public String intiParam1(#RequestBody User user) {
return user.getFirstname();
}
Quick Start with Spring Boot
Related
I was having some problem when trying to access session attribute in Controller. I declared my session attributes as such:
#Controller
#SessionAttributes({ WebKeys.OBJECT_SIX, WebKeys.DSP_LOGIC, WebKeys.NEW_CARD_FORM })
In each of my API, I am calling the function:
#RequestMapping(value = "/apiA.do", method = RequestMethod.POST)
public String doAPIa(Model model) {
setInfo(model);
}
#RequestMapping(value = "/apiB.do", method = RequestMethod.POST)
public String doAPIb(Model model) {
setInfo(model);
}
In my setInfo(), I am trying to access the session attribute and add value back to the model:
private void setInfo(Model model) throws Exception{
String populationId = // need to get from WebKeys.OBJECT_SIX session attribute
if(populationId!=null && (populationId.equals(Constants.POP_TYPE_ID))){
DisplayHelperTO helper = (DisplayHelperTO) // need to get from WebKeys.DSP_LOGIC;
NewCardNewBasicForm newCardForm = (NewCardNewBasicForm ) // need to get from WebKeys.NEW_CARD_FORM);
model.addAttribute("newCardForm", newCardForm);
model.addAttribute("dspLogic", helper);
}
}
I tried to declare in such way:
private void setInfo(Model model,
#SessionAttribute(WebKeys.OBJECT_SIX) String populationId) throws Exception{
}
However, if I am declaring the function in this way, the part to call the setInfo() in both doAPIa and doAPIb will be highlighted in syntax error. Any ideas on how to access the session attributes in function? Thanks!
I am building web service with spring and come across with following problem.
There is a post service as follow.
#RequestMapping(value = "/postSomething", method = RequestMethod.POST)
public ResponseDTO postSomething(#RequestBody ADto aDto){
//post data
//return response
}
public class ADto{
private String firstParam;
private String secondParam;
// getter setter
}
So, my question is how can I know whether value of firstParam and secondParam is provided in request body or not.
RequestBody: { paramFirst: null, paramSecond: null}
Edit1:
Sorry for incomplete question:
For RequestBody: {paramFirst: first Value} and for above request value of paramSecond will be null.
So, how would I know whether paramSecond is included in request or not.
Edit2:
I don't want to validate. What I want to know is whether
request contains a particular parameter or not.
Because there are two different cases, one is value of a parameter is given null and other is paramter is not included in request.
You could use the #Valid annotation like so (pseudo code, didn't test it):
#RequestMapping(value = "/postSomething", method = RequestMethod.POST)
public ResponseDTO postSomething(#Valid #RequestBody ADto aDto){
// MethodArgumentNotValidException will be thrown if validation fails.
}
You'll need an exception handler to handle the validation error.
#ExceptionHandler
#ResponseBody
#ResponseStatus(value = HttpStatus.BAD_REQUEST)
public Error handleException(MethodArgumentNotValidException exception) {
//do something with the validation message: exception.getBindingResult()
}
And your class.
public class ADto{
#NotNull(message = "First parameter can not be null")
private String firstParam;
#NotNull(message = "Second parameter can not be null")
private String secondParam;
// getter setter
}
Try using Hibernate Validator (http://hibernate.org/validator/), it's really easy to integrate it with Spring.
That way, you'll need to annotate your Dto to enforce validation of required params and then call validate.
public class ADto{
#NotNull
private String firstParam;
#NotNull
private String secondParam;
// getter setter
}
#RequestMapping(value = "/postSomething", method = RequestMethod.POST)
public ResponseDTO postSomething(#RequestBody ADto aDto){
validator.validate(aDto)
//post data
//return response
}
You could make firstParam and secondParam type Optional:
ADto class
public class ADto {
private Optional<String> firstParam;
private Optional<String> secondParam;
// getter setter
}
postSomething method
#RequestMapping(value = "/postSomething", method = RequestMethod.POST)
public ResponseDTO postSomething(#RequestBody ADto aDto) {
if (Optional.ofNullable(aDto.getFirstParam()).isPresent()) {
// firstParam is provided in the request
} else {
// firstParam is not provided in the request
}
if (Optional.ofNullable(aDto.getSecondParam()).isPresent()) {
// secondtParam is provided in the request
} else {
// secondtParam is not provided in the request
}
}
Note that isPresent() will return false if and only if firstParam (as well as for secondParam) is not present in the request. Otherwise, even if the value is set to null, it will return true.
I have a controller annotated with #RestController and it implements an interface:
public interface ContratEndpoint {
String ROOT = "/api/contrats";
String GET_CONTRAT = "";
String GET_CONTRAT_PER_PK = "/{idContrat}";
#RequestMapping(value = GET_CONTRAT)
Contrat getContrat(#RequestParam(value = "contratId")Long contratId);
#RequestMapping(value = GET_CONTRAT_PER_ID)
ExtContrat getContratById(#PathVariable("idContrat") Long idContrat);
}
The controller:
#RestController
#RequestMapping(value = ContratEndpoint.ROOT)
public class ContratController implements ContratEndpoint {
//Injecting Services....
#Resource
private Mapper mapper;
#Override
public Contrat getContrat(Long contratId) {
return mapper.map(contratService.get(contratId),Contrat.class);
}
#Override
public ExtContrat getContratById(#PathVariable("idContrat") Long idContrat){
Preconditions.checkArgument(idContrat !=null);
return mapper.map(contratService.get(idContrat),ExtContrat.class);
}
.The above Code works just fine.
. But For the first inherited method , I didn't have to annotate arguments with #RequestParam and it worked just fine.
As for the second method I tried at first :
#Override
public ExtContrat getContratById(Long idContrat){
Preconditions.checkArgument(idContrat !=null);
return mapper.map(contratService.get(idContrat),ExtContrat.class);
}
. I expected the same behaviour Like the first Method, But i was wrong and the code ended up firing an IllegalArgumentException because of the check in ligne Preconditions.checkArgument(idContrat!=null).
My question is what is so specific about #PathVariable that i've missed ?
Or is it just something is wrong with my approach?
Thanks.
There is difference between Request param and path variable,seee below post that you can confirm with your uri the cause for the exception :
#PathVariable is to obtain some placeholder from the uri (Spring call it an URI Template) — see Spring Reference Chapter 16.3.2.2 URI Template Patterns
#RequestParam is to obtain an parameter — see Spring Reference Chapter 16.3.3.3 Binding request parameters to method parameters with #RequestParam
Assume this Url http://localhost:8080/SomeApp/user/1234/invoices?date=12-05-2013 (to get the invoices for user 1234 for today)
#RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
#PathVariable("userId") int user,
#RequestParam(value = "date", required = false) Date dateOrNull) {
...
}
When creating or listing and item using REST api I return also the whole resource path.
For example creating a person record returns http://service:9000/person/1234in response. In order to get schema, host & port part like http://service:9000, I extract it from URL obtained by HttpServletRequest.getRequestURL().
Example (not the production code but conceptually same):
#RequestMapping(value = "/person", method = RequestMethod.PUT)
public Object putPerson(
#RequestParam(value = "name") String name,
HttpServletRequest req) {
long id = createPerson(name);
String uriStart = RestUtils.getSchemeHostPortUrlPart(req
.getRequestURL().toString());
String uri = uriStart + "/person/" + id;
Person person = new Person(name, id, uri);
return person; //Serialized to json by Spring & Jackson
}
//Simple bean-like class
public class Person {
//Getter methods for uri, name & id
}
Since this is quite a boiler plate code which repeats in every method I was wondering if Spring does not have support for this which eluded me when reading it's documentation.
By this I mean accessing either URL without neededn HttpServletRequest or even better its schema, host, port part only.
The documentation provides a lot of examples for constructing URIs using a UriComponentsBuilder.
Furthermore I recommend to take a look at Spring HATEOAS if you want to take your REST API to the next level.
BTW: PUT means that you place what you send (request body) to the location to which you send it (URL). If nothing is there something new is created, otherwise what exists is updated (replaced).
This is not what is happening in your example. The proper way would be to either POST to /person or PUT to the person's own URL, e.g. /person/1234, provided you have the ID beforehand.
You can construct the URI in an interceptor (that's executed previous to controller methods) and put it as an attribute and use it in the controller method.
I believe it is quite simple. Look at this example:
#RequestMapping(value = "/person", method = RequestMethod.PUT)
public Object putPerson(#RequestParam(value = "name") String name, HttpServletRequest req) {
long id = createPerson(name);
Person person = new Person(id, name, req);
return person; //Serialized to json by Spring & Jackson
}
public class JsonResponse {
private String url;
public JsonResponse(HttpServletRequest request) {
url = request.getRequestURI() + "?" + request.getQueryString();
}
public final String url() {
return url;
}
}
public class User extends JsonResponse {
private Long id;
private String name;
public User(Long id, String name, HttpServletRequest request) {
super(request);
this.id = id;
this.name = name;
}
// Getter, Setter
}
You can use org.springframework.web.servlet.support.ServletUriComponentsBuilder like this:
String uri = ServletUriComponentsBuilder.fromCurrentRequest()
.replacePath("/person/{id}")
.buildAndExpand(id)
.toUriString();
I have a Spring MVC backend that needs to start handling new URLs that will be hit by client-side jQuery/AJAX calls. These calls are expecting JSON objects to be returned by the server.
I am trying to follow a few examples I was able to find and here's what I have so far:
// AjaxResult.java
public class AjaxResult {
private int answer;
private String errMsg;
// Getters/setters for both properties.
}
// Inside MyController.java (a Spring #Controller):
public #ResponseBody AjaxResult handleJQueryCall(#RequestParam("x") String whatever) {
int ans = calculateSomething(whatever);
AjaxResult result = new AjaxResult(ans);
return result;
}
I'm not in a position where I can compile/deploy this, but there's clearly something missing here...the use of Jackson! So I ask: how do I specify that the AjaxResult result gets returned by Spring, to the client-side, as JSON? Thanks in advance!
I think You are missing the mapping :
// AjaxResult.java
public class AjaxResult {
private int answer;
private String errMsg;
// Getters/setters for both properties.
}
// Inside MyController.java (a Spring #Controller):
#RequestMapping( value="/myController", method= RequestMethod.GET, produces = "application/json")
public #ResponseBody AjaxResult handleJQueryCall(#RequestParam("x") String whatever) {
int ans = calculateSomething(whatever);
AjaxResult result = new AjaxResult(ans);
return result;
}