Error when calling springRest webservice by an angularJs Client - angularjs

I'm trying to call a web service implementyed by Spring REST but the server respond with 400 http code bad request.I will expose some informations about that Ihope that someone can help me.
This is my controller method:
#RequestMapping(value = "/addpost", method = RequestMethod.POST,headers = "Accept=application/json")
public #ResponseBody
String addpost(#RequestBody PostDto post, #RequestBody UserDto user) {
postservice.addPost(post, user);
return "post inserted";
}
The manner by that I call the web service:
$scope.addPost = function() {
$scope.addPost = function() {
$http({
method : 'POST',
url : 'http://localhost:8080/wall/addpost',
data : ({
post : $scope.postt,
user : $scope.userr
}),
}).success(function(data, status, headers, config) {
// $scope.persons.push(data);
alert("Success");
$scope.user = "";
$scope.post = "";
}).error(function(data, status, headers, config) {
alert("erreur");
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
};
the tow objects "userr" and "postt":
$scope.userr = {
userId : 15,
firstName : "foulen",
lastName: "ben foulen"};
$scope.postt = {
Id : "18",
datePost : null,
note: "Mon message"};
The response of the server:
Etat HTTP 400 - Required PostDto parameter 'post' is not present
these are the headers of request and reponse:
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/wall/addpost
Request Method:POST
Status Code:400 Mauvaise Requête
Request Headersview source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:125
Content-Type:application/json;charset=UTF-8
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/wall/view/test.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
Request Payloadview source
{post: {idpost: 18, datePost: null, note: "Mon message"},…}
post: {idpost: 18, datePost: null, note: "Mon message"}
datePost: null
idpost: 18
note: "Mon message"
user: {userId: 15, firstName: "foulen", lastName: "ben foulen"}
firstName: "foulen"
lastName: "ben foulen"
userId: 15
Response Headersview source
Connection:close
Content-Length:983
Content-Type:text/html;charset=utf-8
Date:Fri, 27 Feb 2015 11:16:49 GMT
Server:Apache-Coyote/1.1

You cannot use two #RequestBody as it can bind to a single object only (the body can be consumed only once).the much easier way would be to introduce a wrapper Object and change your signature.

The parameters whichever you are passing , are they getting passed to the controller ? I mean to the url you mentioned in the angular controller
'http://localhost:8080/wall/addpost'.

your Angular codes seems good. I think that the problem is on the side of the server codes. The request parameter #RequestParam PostDto post should have a value to indicate its name, like this : #RequestParam PostDto("post") post. According to spring doc, this value by default is "".
To complete, maybe you should use a more normal way of sending request of Angular. I mean to use the json object for the parameters, but not the html form. Because you have already your models of user and post.
Hope help.
EDIT :
Can you modify your angular codes, to send the parameter by json object.
$http({
method : 'POST',
url : 'http://localhost:8080/wall/addpost',
data : ({
post : $scope.postt,
user : $scope.userr
})
}).success(function(data, status, headers, config) {
// $scope.persons.push(data);
alert("Success");
$scope.user = "";
$scope.post = "";
}).error(function(data, status, headers, config) {
alert("erreur");
// called asynchronously if an error occurs
// or server returns response with an error status.
});
};
And delete the header in your java codes :
#RequestMapping(value = "/addpost", method = RequestMethod.POST)
public #ResponseBody
String addpost(#RequestParam(value="post") PostDto post, #RequestParam(value="user") UserDto user) {
postservice.addPost(post, user);
return "post inserted";
}
EDIT :
model:
$scope.postInfo= {
userId : 15,
firstName : "foulen",
lastName: "ben foulen",
postId : "18",
datePost : null,
postnote: "Mon message"
};
AJAX:
$http({
method : 'POST',
url : 'http://localhost:8080/wall/addpost',
data : ({
post : $scope.postInfo
}).// your other codes
})
JAVA :
#RequestMapping(value = "/addpost", method = RequestMethod.POST)
public #ResponseBody String addpost(#RequestBody PostInfoDto post) {
// codes...
}

Related

Http POST 405 errror in Angularjs with Spring MVC

Actually I want to integrate Spring with Angularjs and i am beginner in Angularjs. When i use $http post method it return POST 405.Here is my code
SignUp.html
<form method="post" ng-submit="saveUser()">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
myApp.js
var myApp = angular.module('myApp', ['ngMessages']);
UserIdController.js
myApp.controller('UserIdController', [
'$scope',
'UserIdService',
function($scope, UserIdService) {
$scope.saveUser = function() {
UserIdService.saveUser($scope.user).then(
function success(response) {
console.log("user Added");
}, function error(response) {
console.log("User not Added")
});
}
} ]);
UserIdService.js
myApp
.service(
'UserIdService',
[
'$http',
function($http) {
this.saveUser = function saveUser(user) {
return $http({
method : 'post',
url : 'SignUpUser',
data : {
firstName : user.firstName
},
headers : 'Content-Type: application/json'
});
}
} ]);
Spring REST Controller
#RestController
#Produces("text/plain")
public class SignUpController {
private static final Logger logger =
LogManager.getLogger(SignUpController.class);
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#PathVariable String firstname) throws
ParseException {
logger.debug("Enter in SignUp Controller in Post Method");
UserDetails userDetails = new UserDetails();
studentDetails.setFirstName(firstname);
return "ok";
}
I got this error in Chrome in Inspect element
Request URL:http://localhost:8080/examapp/signup
Request Method:POST
Status Code:405
Remote Address:[::1]:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
view parsed
HTTP/1.1 405
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Allow: GET
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en
Content-Length: 1084
Date: Fri, 04 Aug 2017 05:50:32 GMT
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:26
Content-Type:application/json
Cookie:JSESSIONID=ACF3E30CB7B3A6A9862F923F42DB61B5
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/examapp/signup.html
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36
Request Payload
Does anyone have an idea of what I'm doing wrong? It seems like a pretty straight forward implementation that is working on all of the tutorials I've seen yet. Any help will be appreciated. Thank you.
Please add #RequestMapping("/examapp") over yourSignUpController
#RestController
#Produces("text/plain")
#RequestMapping("/examapp")
public class SignUpController {
You have specified #PathVariable here. A path variable is just that, a variable from the path. What you want is #RequestBody.
In your scenario, Spring has nothing maped to /SignUpUser, it is looking for /SignUpUser/{firstName}, but since #RequestMapping doesn't specify {firstName}, you are essentially posting to a non-existent resource.
Although unrealistic in the real world, to post just a first name to login, In your $http.post, you would just want data : user.firstName.
In your Spring controller:
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#RequestBody String firstname)
The Right Fix
If you want your back-end to accept what you have in Angular (more real-world), you would create a POJO class, and accept that (#RequestBody UserDetails request). It appears you have the UserDetails POJO created, so you just have to accept that instead:
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#RequestBody UserDetails userDetails ) {

Fetch Angular $http response header param

I am working on an Progressive Web app module with AngularJS.
I have made a network call with POST request using '$http', I am able to get a response of it but am not getting 'Response Header' params.
Here is my Response header:
Connection:keep-alive
Content-Type:application/json
Date:Fri, 19 May 2017 10:41:49 GMT
Server:JBoss-EAP/7
Session-ID:XXXXX-YYYY-ZZZ
Transfer-Encoding:chunked
X-Powered-By:Undertow/1
And below is a request and API call.
$scope.data = {userid: $scope.username,
os: 'android',
device_id: 'b0316b93ae786ec0',
source: 'iv2',
password: $scope.password,
build_version_code: '2.3',
version: '5.1.1'};
$http({
method : "POST",
url: 'https://domain.name/v1/users/login',
data : $scope.data,
headers: {
'content-type': "application/json",
'sessionID': ''
}
})
.then(function successcallback(response){
console.log("Session-ID" , response.headers());
console.log("response" , response);
}, function errorcallback(response){
console.log('error' , response);
});
I have tried below possible solution based on response callback method.
function successcallback(response){
response.header('Session-ID');
}
and
success(function(response , status , headers , config){
console.log("response" ," headers - " + headers('Session-ID'));
}
The both approaches returns a null value instead of expected value.
Please let me know if I am missing something. I am happy to get all possible help.

Angular $http.post 1.6.1 not passing data to WebAPI

All, I just created a new Angular package using 1.6.1 but now the data doesn't seem to pass to my WebAPI. However, when I post bits via SoapUI or something like that, everything is fine.
The Javascript looks like this:
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: 'PassInTheText'
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};
function goodResponse(response)
{
console.log("Good response");
console.log(response);
}
function badResponse(response)
{
console.log("Bad response");
console.log(response);
}
and the webapi is a very simple C# controller:
// POST api/values
public HttpResponseMessage Post([FromBody]string value)
{
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent(value);
return rp;
}
I am making it into the controller, I can set a break point and hit the parts where I can look at the value. It's always null.
Looking at the network trace, the angular part does do a preflight and I can see the 200 response back.
Request URL:http://server/testangular16/api/Values
Request Method:OPTIONS
Status Code:200 OK
Remote Address:10.7.14.209:80
**Response Headers view source**
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Origin:http://localhost:8000
Cache-Control:no-cache
Content-Length:0
Date:Fri, 03 Feb 2017 18:09:04 GMT
Expires:-1
Pragma:no-cache
Server:"Management Corporation"
X-AspNet-Version:4.0.30319
**Request Headers view source**
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:mjvzrx3
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
So, it looks like I'm passing CORS, but when I get to trying to pass the data in as the content of the post, it doesn't make it.
Any ideas what I'm missing?
Thanks,
Nick
Web API expects an object in the message body, you cant pass in a primitive type unless you use application/x-www-form-urlencoded as the content-type and prefix the value with an equals = sign.
So you can fix it by one of these methods
Adjust the c# parameter and turning it into a type that has a string property and then send in a json object with a matching parameter name.
Change the request to url-encoding content type and add a = to the variable value.
Send it as a part of the URL instead of the message body, you can still use the POST method.
Change to form-urlencoded
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: '=PassInTheText', // added =
contentType: 'application/x-www-form-urlencoded' // specify content type
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};
It seems if I do this, it works as expected.... Thoughts?
// POST api/values
public HttpResponseMessage Post(HttpRequestMessage request)
{
var data = request.Content.ReadAsStringAsync().Result;
Console.WriteLine("Data: {0}", data);
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent("Data back from WebAPI" + data);
return rp;
}

unsupported Media type 415 for file upload with Spring mvc restcontroller and angularjs

When i am trying to hit the angularjs $http.post which contains file upload details its giving me unsupported media type. I am using backend spring mvc rest controller. The following is the code snippet.
<ul><li><h4>Document Type</h4>
<select name="docType" ng-model="docType" name="docType">
<option value="Report1">Report1</option>
<option value="Report2">Report2</option>
</select>
<input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />
</li>
<li><h4>Comments:</h4><textarea></textarea></li>
<li><button class="btn-panel-blue" type="submit">Saves</button></li>
<li>Cancel</li>
</ul>
angular.module('app')
.controller('prjCntrl', function ($scope,projectService, sharedService, $location, $log, $http, $state) {
$scope.setFiles = function(element) {
$scope.$apply(function(scope) {
$scope.uploadedFile ;
for (var i = 0; i < element.files.length; i++) {
$scope.uploadedFile=element.files[i];
break;
}
});
};
$scope.updateProject = function updateProject()
{
var formData=new FormData();
formData.append('docType',angular.toJson($scope.projectData.docType,true));
formData.append("uploadFile",$scope.uploadedFile);
var url=baseURL + '/updateProject.do';
$http.post(url, formData, { transformRequest: angular.identity, headers: {'Content-Type': undefined} })
.success(function(){alert("success");})
.error(function(){ });
};
}
);
and here is my java code.
#RestController
#MultipartConfig(fileSizeThreshold=1024*1024*10,
maxFileSize=1024*1024*50,
maxRequestSize=1024*1024*100)
public class ProjectController {
#RequestMapping(value="/updateProject.do",method = RequestMethod.POST,headers ="Accept=multipart/form-data", consumes={"multipart/form-data"}, produces={"text/plain;charset=UTF-8"})
public #ResponseBody String updateProjectDetails(HttpServletRequest request, HttpServletResponse response, #RequestBody ProjectForm command)
{
contractProjectsService.saveProject(command);
return "success";
}
}
here is the header information from chrome headers/request and response data
**General:**
Request URL:http://localhost:9090/SpringMVCAngularJS/updateProject.do
Request Method:POST
Status Code:415 Unsupported Media Type
Remote Address:[::1]:9090
***Response Headers:***
view source
Content-Language:en
Content-Length:1048
Content-Type:text/html;charset=utf-8
Date:Wed, 03 Aug 2016 15:06:05 GMT
Server:Apache-Coyote/1.1
***Request Headers:***
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Authorization:Basic YmVlcDpib29w
Connection:keep-alive
Content-Length:1011
Content-Type:multipart/form-data; boundary=---- WebKitFormBoundaryagdf0LOX4AuXY6SI
Cookie:JSESSIONID=96052E348C6E52F53A594A179E65DE6D
Host:localhost:9090
Origin:http://localhost:9090
Referer:http://localhost:9090/SpringMVCAngularJS/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Please help me with the solution.
try to send the comment or other data in request header and send file to contoller ,in controller use" #Requestpart" for accepting file. Use below code for reference..
#Produces("text/plain;charset=UTF-8")
#RequestMapping(value = "/fileUpload/", method = RequestMethod.POST)
public #ResponseBody ResponseCodeModel fileUpload(#RequestPart MultipartFile file,
#RequestHeader(value = "comment") String comment,
)

spring RESTcontroller to accept dataURI

I am running into a issue of using angularjs ng-img-crop and Spring-boot REST web service.I want to upload an image file from ng crop to my backend web service.
I tried writing a spring controller but it failed and I couldnt find a good tutorial for this. help me resolve this basic request.
Thanks !!!
app.js
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version',
'ngImgCrop'
])
.controller('Ctrl',['$scope','notify', function($scope,notify) {
$scope.myImage='';
$scope.myCroppedImage='';
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
$scope.submit=function() {
notify($scope.myCroppedImage);
};
}]).
factory('notify',['$http', function($http) {
return function(myCroppedImage) {
var name = 'vishnu';
$http.post('http://localhost:8080/imageUpload', myCroppedImage)
.success(function(data, status, headers, config) {
alert("success");
})
.error(function(data, status, headers, config) {
alert("fail");
});
}
}])
controller.java
#RequestMapping(value="/imageUpload",method=RequestMethod.POST)
#ResponseBody
public String imageUpload(#RequestBody MultipartFile data){
return "success";
}
when I run with the following request, I got some exception in the web service.
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/imageUpload
Request Method:POST
Status Code:500 Internal Server Error
Request Headersview source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:1850
Content-Type:application/json;charset=UTF-8
Host:localhost:8080
Origin:file://
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36**
Request payload
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAFIklEQVR4Xu3VsRHAMAzEsHj/pTOBXbB9pFchyLycz0eAwFXgsCF.......
Response header
Connection:close
Content-Type:application/json;charset=UTF-8
Date:Fri, 24 Apr 2015 12:40:35 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
Exception in java
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
First of all your controller should looks like:
public ResponseEntity<Response> fileUpload(#RequestParam("file") MultipartFile file) {
Use #RequestParam instead of #RequestBody, and send the file in a parameter with the same name you're using in the annotation.
Moreover, your request should be sent with type multipart/form-data. For example, a common html for would be:
<form method="POST" enctype="multipart/form-data" action="your url">

Resources