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
Related
I am trying to get string "Error. Does this link come from email? Or maybe you have used your token already?" as a response if requesty is not correct (excactly such response I get in Postman) or "You have successfully changed your password." if request is ok, but instead of that on my website when I get directly from param of subscribe I get Object object, but when I use function JSON.stringify then I get something like that.
Here is my code:
submitFunc() {
this.data = '';
if (this.uploadForm.invalid) {
console.log('Password validation invalid')
return;
}
console.log('Password validation correct')
const response = this.restapiService.postResetPassword(this.tokenFromUrl, this.uploadForm.controls['password'].value);
response.subscribe(data => { console.log('a '+JSON.stringify(data)); },
error => { console.log('b '+JSON.stringify(error)); });
}
and
public postResetPassword(token: string, password: string): Observable<any> {
const body = {
'token': token,
'password': password
};
const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
return this.http.post<any>('https://jakuwegiel-backend.herokuapp.com/reset_password', body,{headers: headers});
}
and my part of controller in backend
#PostMapping(value = "/reset_password", consumes="application/json")
public String processResetPassword(#RequestBody TokenAndPassword tokenAndPassword) {
try {
User user = userService.getByResetPasswordToken(tokenAndPassword.getToken());
if (user == null) {
return "message";
} else {
userService.updatePassword(user, tokenAndPassword.getPassword());
System.out.println("You have successfully changed your password.");
}
}
catch (Exception ex) {
System.out.println("aaaaaaaaaaaaa " +ex.getMessage());
return "Error. Does this link come from email? Or maybe you have used your token already?";
}
return "You have successfully changed your password.";
}
Is there anything you need more?
You need to console.log(error.error.text). And then you will be able to make this value in your text message.
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.
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.
I post two Headers from a js file in a GET REST Call:
allstaffworking: function(_getstaff){
var currentToken = _GetToken();
var Headers = {
token: currentToken.tokenStaff,
};
var HeaderId = {
idtoken: currentToken.idtokenStaff,
};
console.log("idtoken"+Headers);
if (currentToken !== null) {
$http({
method : 'GET',
headers: Headers, HeaderId,
url : REST_URL+'staff/working'
}).then(function successCallback(response) {
_getstaff(response)
}, function errorCallback(response) {
console.log(response.statusText);
});
} else {
console.log("NON SEI LOGGATO!!!");
}
},
The Headers are:
var Headers = {
token: currentToken.tokenStaff,
};
var HeaderId = {
idtoken: currentToken.idtokenStaff,
};
This is the java page called by REST_URL+'staff/working':
public List<Staff> getStaff()
{
List<Staff> listOfStaff=sDao.getAll(Staff.class);
return listOfStaff;
}
#GET
#Path("/working")
#Produces(MediaType.APPLICATION_JSON)
#Consumes("application/json")
public List<Staff> getWStaff(#HeaderParam("token") String token, #HeaderParam("idtoken") int tokenid)
{
s = (Staff) sDao.getById(tokenid, Staff.class);
st = (StaffType) sDao.getById(s.getStaffType().getIdstaffType(), StaffType.class);
if (ex && st.getIdstaffType()==2){
List<Staff> listOfWStaff=stfDao.getAllW();
return listOfWStaff;
}
else
return null;
}
taking the two Header with: #HeaderParam("token") String token, #HeaderParam("idtoken") int tokenid
The first Header Param works, the second doesn't works, look this debug's image
How you can see from the image, the idtoken's header value is 11.
Therefore my java class should work taking this second #HeaderParman such int. But it doesn't work, error 500. I try to manually insert "11" , in this way:
s = (Staff) sDao.getById(11, Staff.class);
And in this way it works!! Then, the mistake is when I take the second #HeaderParam, I've also tried with take tokenid as String, an convert it using Integer.parseint(tokenid)
but it does not change.
I hope that somebody can help me
$http config object's header property takes an object as param, as you are passing 2 objects its picking the first one. Ideally you should pass something like this:
$http({
...
headers: {
token: currentToken.tokenStaff,
idtoken: currentToken.idtokenStaff
}
...
});
Also I am curious as to why you are not getting error in line where you are providing Headers and HeaderId as comma separated.
FrontEnd: jsp with AngularJS
BackEnd: Spring MVC/Java
I am uploading a file using ng-flow, angularJS. Source: https://github.com/flowjs/ng-flow
File upload is successful. I need to return a json from my Spring Controller. Any clues how to go about it?
P.S. can't find where to put in .success() function, if at all that is applicable.
Spring Controller:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String uploadFileHandler(#RequestParam("file") MultipartFile file, Model model) {
//Upload file and process
JsonObject jo = Json.createObjectBuilder().add(path, folderPath.toString())
.add(aContentsAttrib, aContents)
.add(bContentsAttrib, bContents).build();
}
app.js code:
(function() {
var app = angular.module('app', ['flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
flowFactoryProvider.defaults = {
target: 'upload',
permanentErrors: [404, 500, 501],
maxChunkRetries: 4,
chunkRetryInterval: 500,
simultaneousUploads: 4
};
flowFactoryProvider.on('catchAll', function (event) {
console.log('catchAll', arguments);
});
// Can be used with different implementations of Flow.js
// flowFactoryProvider.factory = fustyFlowFactory;
}]);
app.controller('PageController', function() {
//this.products = gems;
});
app.controller("TabController", function() {
this.tab = 1;
this.showOutput = false;
this.viewEvents = false;
this.isSet = function(checkTab) {
return this.tab === checkTab;
};
this.changeVal = function() {
this.viewEvents = true;
};
this.setTab = function(setTab) {
this.tab = setTab;
};
});
})();
What exactly should be returned from the spring controller? (String/#ResponseBody String etc)
How to collect that json in angular?
On your controller #ResponseBody should be added and the jo returned as String:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public #ResponseBody String uploadFileHandler(#RequestParam("file") MultipartFile file, Model model) {
//Upload file and process
JsonObject jo = Json.createObjectBuilder().add(path, folderPath.toString())
.add(aContentsAttrib, aContents)
.add(bContentsAttrib, bContents).build();
return jo.toString();
}
In AngularJS, you should do this for being able to post files and then retrieve the data back:
$http({url: '/url',
method: 'POST',
data: $scope.myFile,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(data){
$scope.myData = data;
});
In your Spring controller you should just return an Object containing the properties you want to transfer to your angular service. This will be automatically (or by default) be converted to JSON. #RequestBody is not needed.
This return value will be available in the success callback, something like:
$http({
method: 'POST',
url: '...',
}).success(function (data) {
//data is your JSON response
})},
If you are using Spring 3 you can do this
#RequestMapping(value = "/getDealers", value = "/upload", method = RequestMethod.POST)
#ResponseBody
public String uploadFileHandler() {
}
#ResponseBody annotation directly writes the response to the response stream. You would not need a JSP. Just send the request for the controller from the browser & the controller method will write the response to the response stream.
You can parse the response using Jquery or any json library & display in the JSP
Check this out
An alternate way, which I just found out. Will be useful to extract from existing code, without any modification. It does introduce an extra global variable, outside your main angular app, and might not be highly recommended, but still, posting this.
var json = {};
var app = angular.module('app', ['flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
flowFactoryProvider.defaults = {
target: 'processxls',
permanentErrors: [404, 500, 501],
maxChunkRetries: 4,
chunkRetryInterval: 500,
simultaneousUploads: 4
};
flowFactoryProvider.on('catchAll', function (event) {
console.log('catchAll', arguments);
this.jsonResponse = arguments[2]; //Note this change
//json = this.jsonResponse;
console.log(this.jsonResponse);
json = angular.fromJson(this.jsonResponse);
});
// Can be used with different implementations of Flow.js
// flowFactoryProvider.factory = fustyFlowFactory;
}]);
'json' variable now has the json response received. You can use it for further use now.
P.S. in order to check for which value of 'i' arguments[i] gives you the json, see console.