Angularjs-Spring : Getting parameter as Null in controller - java

Here is the code for the controller
#RequestMapping(value = "/fetchRecord/", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(Integer primaryKey)
{
return this.serviceClass.fetchRecord(primaryKey);
}
Here is my angular code
var dataObj = {
primaryKey : $scope.primaryKey
};
var res = $http.post('/Practice/learn/fetchRecord/', dataObj);
res.success(function(data, status, headers, config) {
$scope.firstname = data;
});
res.error(function(data, status, headers, config) {
alert("failure message: " + JSON.stringify({
data : data
}));
});
i am able to debug my code. Although i can check it in browser that value for primaryKey get passed. But still it is null in controller.
any possible reason for that ?

You should send a json object,
try this,
var dataObj = {
primaryKey : $scope.primaryKey
};
var res = $http.post('/Practice/learn/fetchRecord/', angular.toJson(dataObj));

You can get the value in the Controller from two ways:
First option:
Assign an object that has the attribute you want to pass.
Suppose that you have RecordEntity object, it has some attributes, one of them is the Integer primaryKey. The annotation #RequestBody will receive the value, so the controller will be:
backend
#RequestMapping(value = "/fetchRecord/", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(#RequestBody RecordEntity recordEntity) {
return "primaryKey from requestBody: " + recordEntity.getPrimaryKey();
}
frontend
In the frontend you should send an json that has the primaryKey attribute in the body, for example:
http://localhost:8080/Practice/learn/fetchRecord/
Post body:
{
"primaryKey": 123
}
You controller will receive the value in the RecordEntity object.
Second option:
Pass the value by URL, the annotation #RequestParam will receive the value, so the controller will be:
backend
#RequestMapping(value = "/fetchRecord", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(#RequestParam Integer primaryKey) {
return "primaryKey from RequestParam: " + primaryKey;
}
frontend
In the url you should send the value with ?primaryKey, for example
http://localhost:8080/Practice/learn/fetchRecord?primaryKey=123
You controller will receive the value in the Integer primaryKey.

Related

Data is passed within ""(doublequotes) from angularJs to SpringMVC Controller

I am passing data from controller.js to service.js to SpringController.java
but weird thing is happening when i pass $scope.credentials.uname data to Java Controller .
The data passed is coming in doublequotes . When i print the value in Java
its getting printed as "USER" instead of USER.
Also due to this i am not able to save the username in database.
$scope.submitUsername = function()
{
$log.info("username "+$scope.credentials.uname);
Here log is getting printed properly chrome console
username SYS_USER --> without double quotes
loginService.fetchUserType(angular.copy($scope.credentials.uname)).then(function(data)
{
if (data.loginType == 'NotValidUsername')
{
$log.info("Failure")
toaster.pop('information', "Warning", 'Enter Valid UserName');
}
else
{
$log.info("Success")
if (data.loginType == 'database')
{
$scope.isExternalUser = true;
$scope.showSubmitButton = false;
}
else
{
$scope.isExternalUser = false;
$scope.showSubmitButton = false;
}
}
})
};
service.js
fetchUserType : function(userName)
{
var promise = $http({
url : "checkUserType.do",
method : "POST",
data : JSON.stringify(userName)
}).success(function(data, status, header, config, statusText)
{
}).error(function(data, status, header, config, statusText)
{
if(!status === 901)
toaster.pop('error', status, statusText);
}).then(function(response)
{
return response.data;
})
return promise;
}
Java Controller method
#RequestMapping(value = "/checkUserType.do", method = { RequestMethod.GET, RequestMethod.POST })
#ResponseBody
public Object checkUserType(#RequestBody String username,HttpServletRequest request)
{
log.info(" Inside checkUserType "+username);
User user = new User();
user.setUserName(username);
String userType = loginService.checkUserType(user.getUserName());
user.setLoginType(userType);
return user;
}
Output on console is
Inside checkUserType "SYS_USER".
How should i pass data so that i can avoid these ""(doublequotes) being passed to Java Controller
Remove JSON.stringify(userName) from your service.js This is whats adding the double quotes around your request.
Instead your data should just be data: userName. When it gets send to your controller it will be correctly converted to json for your controller to digest.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

Get values from received html body

I want to get the body values from received html request body using Spring boot:
#PostMapping(value = "/v1/notification")
public ResponseEntity<String> handleNotifications(
#RequestParam(value = "uniqueid", required = false)) String uniqueidValue,
#RequestParam(value = "type", required = false)) String statusValue) {
// Get values from html body
return new ResponseEntity<>(HttpStatus.OK);
}
For example when I receive into the notification body:
some_key=some_value&sec_key=sec_value
I would like to parse the values. How I can implement this?
You can take the key value pair request with using Map and #RequestBody as below:
#PostMapping(value = "/v1/notification")
public ResponseEntity handleNotifications(#RequestBody Map<String,String> keyValuePairs) {
// here you can use keyValuePairs
// you can process some specific key like
String value = keyValuePairs.get("someSpecificKey");
return ResponseEntity.ok(value);
}
Here I attach example postman request :

Swagger example post body - how to show JSON Body- Swagger-annotations

Requirement: I have a POST method which takes the input JSON as a String and passes it to another microservice. I don't want to create an Object (Bean) of this input JSON.
method:
#ApiOperation(notes = "example" value = "/example", consumes = ".." , method= "..")
#RequestMapping(name = "xxx" value ="/hello" ..)
#ApiResponses(..)
public #ResponseBody String getXXX (#Apiparam(name="JSONrequest", required = true) #RequestBody String JSONrequest){
}
Problem:
The generated Swagger doesn't show the input as a JSON model where all the JSON attributes are displayed.
Expectation:
I want to display my Swagger Something like this :
Definately I am missing the key thing. Any thoughts?
If changing from String to a concrete object is not okay (although that's what I would recommend you to do since it's cleaner), you can try using #ApiImplicitParams (check out their documentation)
#ApiOperation(notes = "example" value = "/example", consumes = ".." , method= "..")
#ApiImplicitParams({
#ApiImplicitParam(name = "Object", value = "Object to be created", required = true, dataType = "your.package.BodyClass", paramType = "body")
})
#RequestMapping(name = "xxx" value ="/hello" ..)
#ApiResponses(..)
public #ResponseBody String getXXX (#Apiparam(name="JSONrequest", required = true) #RequestBody String JSONrequest){
}
(not sure if you still need the #Apiparam(name="JSONrequest", required = true) bit from the method parameter)
It's an old question but since I haven't found a solution online here how I to customized the example value in the swagger documentation produce automatically by the java annotations.
I use swagger 2.0 and springfox.version 2.10.5.
The Idea is documenting the class of the request parameter that has the #RequestBody annotation. for example my method is
#ApiOperation(
value = "Start ListBuilder extraction",
response = ExtractionLogEntity.class,
produces = "application/json"
)
#PostMapping("/extraction/start")
public ExtractionLogEntity startTask(
#RequestBody(required = true) ExtractionRequest request,
In order to expose request json object example I added a #ApiModelProperty(example = "...") annotation to the properties of ExtractionRequest .
#ApiModelProperty(example = "[{ 'field':'value'}]")
#NotNull
private List<ListBuilderFieldEntity> fields;
#ApiModelProperty(example = "1000")
private String ied;
#ApiModelProperty(example = "US")
private String codebase;
And that's the result
I had the similar issue. My Service Class takes #RequestBody argument in String.
So, what I did :
Created a POJO and used #RequestBody annotation with it instead of inputString.
#RequestMapping(value = "/api/entity/{entityId}/user/query", method = {RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody
ResponseEntity<String> queryUser(#PathVariable("entityId") String entityId,
#RequestBody QueryUserJsonSchemaPOJO queryUserJsonSchemaPOJO, String inputString,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return userService.queryUserService(inputString, entityId, request);
}
Created an AOP with #Around annotation which update the inputString argument.
#Around(value = "execution(* com.athmin.rest.UserController.*(..)) || execution(* com.athmin.rest.CityController.*(..)), and args(..) " +
" && #annotation(com.athmin.annotations.JSONSchemaFileName) ")
public Object validateRequestBodyAgainstJsonSchema(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] modifiedArgs = proceedingJoinPoint.getArgs();
for (Object o : proceedingJoinPoint.getArgs()) {
if (o instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) o;
requestBody = httpServletRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
}
});
for (int i = 0; i < modifiedArgs.length; i++) {
if (modifiedArgs[i] == null) { // Only inputString is null in my case
modifiedArgs[i] = requestBody;
}
}
proceedingJoinPoint.proceed(modifiedArgs);
}

Spring Boot #RestController no respond

I'm starting with Spring and REST application. Currently, I'm developing one application on my own and I stuck.
The app is divided just like standard Spring Boot project. All of the controllers are contained in web package.
One of "standard" controller is responsible for handling HTTP request and returning an HTML website. I have added a REST controller which should respond to POST request from the first controller, but I receive a 404 error.
How it looks like in code?
#RestController
#RequestMapping("/users")
public class UserRestController {
#Autowired
private UserService userService;
#RequestMapping(value = "/user", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public ResponseEntity<?> getUser(#RequestParam("userId") String userId, Errors errors) {
AjaxUser response = new AjaxUser();
if (errors.hasErrors()) {
response.message = errors.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.joining(","));
return ResponseEntity.badRequest().body(response);
}
response.setUser(userService.getUserById(Integer.getInteger(userId).intValue()));
return ResponseEntity.ok(response);
}
private class AjaxUser {
private User user;
private String message;
public void setUser(User user) {
this.user = user;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
#Override
public String toString() {
return "User { id:" + user.getId() + ", Name: " + user.getName() + ", surname: " + user.getSurname() + "}";
}
}
}
From .js file I send a ajax query which should trigger a rest controller, here is the code:
function sendUserId(id) {
var user = {};
user["userId"] = id;
console.log("USER: ", user);
$.ajax({
type: "POST",
contentType: "application/json",
url: "/users/user",
data: JSON.stringify(user),
dataType: 'json',
cache: false,
timeout: 100000,
success: function (user) {
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(user, null, 4) + "</pre>";
console.log("SUCCESS : ", user);
},
error: function (e) {
var json = "<h4>Ajax Response</h4><pre>"
+ e.responseText + "</pre>";
console.log("ERROR : ", e);
}
});
}
userId is taken from a html by jQuery, console.log show existing and right value.
Note: There exist a standard user #Controller which is responsible for displaying a user list, it works, problem appear during sending a user id to REST controller. It behaves just like the REST controller doesn't exist and browser return 404 status response. Btw, page use a Spring Secure to login and so on.
Could someone help?
BR Konrad
The controller is looking to have a request parameter that you are missing in the js requesting url
/users/user?userId=1
You can get a user by id like below:
#RequestMapping(value = "{id}", method = RequestMethod.GET)
public ResponseEntity<User> get(#PathVariable("id") int id) {
User user = userService.findById(id);
if (user == null) {
return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
So your rest entry point is /users/userid, eg: /users/1
Found this from the post Spring MVC RESTFul Web Service CRUD Example
the problem based on function arguments, REST controller should take String argument and next parse it to JSON object, the response should be String too. Topic can be closed, thanks all to be involved.

How do I retrieve query parameters in a Spring Boot controller?

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

Categories