Passing String from angular to Spring using #Requestbody - angularjs

I am working on a project using angularjs+springboot. Am trying to send email via my application using spring-boot-starter-mail. The message and object of the email are written by the user in a form. what I want to do is to get the message and object values in my RestController using #RequestBody.
the function in my service.js
// send mail
var sendMail = function(id, objet, msg) {
var deferred = $q.defer();
$http.post(urlBase + id, objet, msg).then(
function(response) {
deferred.resolve(response.data);
}, function(errResponse) {
console.error('Error while sending email');
deferred.reject(errResponse);
});
return deferred.promise;
}
the method in my restContoller
#RestController
public class EmailController {
#Autowired
private JavaMailSender javaMailSender;
#Autowired
UtilisateurService service;
#RequestMapping(value = "/users/{id}", method = RequestMethod.POST)
public ResponseEntity<Void> sendMail(#PathVariable("id") int id, #RequestBody String objet,
#RequestBody String msg) {
Utilisateur currentUser = service.findById(id);
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(currentUser.getEmailUtil());
message.setSubject(objet);
message.setText(msg);
javaMailSender.send(message);
return new ResponseEntity<Void>(HttpStatus.OK);
}}
This throws this exception :
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.Void> com.sla.utilisateur.controller.EmailController.sendMail(int,java.lang.String,java.lang.String)
How can I fix it?
thank you,

Your usage of $http.post is not correct. You should have a look at the AngularJS POST documentation. $http.post arguments are the following:
post(url, data, [config]);
AngularJS sends the data by default in JSON. So you should send the request using the following statement (for example):
$http.post(urlBase + id, {subject:objet, body:msg})
And in your controller you should define only one #RequestBody maps for the ease of the example to a Map (You could change it to a POJO. ):
#RequestMapping(value = "/users/{id}", method = RequestMethod.POST)
public ResponseEntity<Void> sendMail(#PathVariable("id") int id, #RequestBody Map<String,String> msg) {
Utilisateur currentUser = service.findById(id);
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(currentUser.getEmailUtil());
message.setSubject(msg.get("subject");
message.setText(msg.get("body"));
javaMailSender.send(message);
return new ResponseEntity<Void>(HttpStatus.OK);
}}

Related

Error while sending json from angular to spring controller

I am trying to send json data from angularjs service to controller in spring.
But getting error:
angular.js:10661 POST http://localhost:8080/shoping/product/add 500 (Internal Server Error)
product_service.js:35 Error while adding product
product_controller.js:30 {productId: null, productName: "sdfv", productPrice: 43, description: "sfdv", imageUrl: "csd"}
This is my function in service in angularJs
function addProduct(product){
var deferred = $q.defer();
$http.post(REST_SERVICE_URI+"add", product)
.then(
function(response){
deferred.resolve(response.data);
},
function(errResponse){
console.log('Error while adding product');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
This is my method in spring controller
#RestController
#RequestMapping("/product/")
public class ProductRestController {
#Autowired
ProductDao productDao;
RequestMapping(value = "add", method= RequestMethod.POST, consumes="application/json")
public ResponseEntity<Void> createProduct(#RequestBody Product product) {
System.out.println("Creating Product " + product.getProductName());
if (productDao.isProductExit(product)) {
System.out.println("A Product with name " + product.getProductName() + " already exist");
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
productDao.add(product);
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
Also I have a $http.delete method in angular service
$http.delete(REST_SERVICE_URI+"delete/"+id)
And there is also an error saying Syntax error on token ".", , expected
UPDATE
Product.java
#Entity
#Table(name ="product")
public class Product implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="product_id")
private int productId;
#Column(name = "product_name")
private String productName;
#Column(name = "product_price")
private Float productPrice;
#Column(name = "description")
private String description;
#Column(name = "image_url")
private String imageUrl;
//getter and setter
UPDATE: 2
Sorry the NUllPointerException was occuring when I tried to send empty json . There is no error in the spring console
MainController.java
#Controller
#RequestMapping("/")
public class MainController {
#Autowired
UserDao userDao;
#RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
public String defaultPage() {
return "ProductManagement";
}
Now the error in angluar is :
angular.js:10661 POST http://localhost:8080/shoping/product/add 404 (Not Found)
UPDATE 3:
When I make get request instead of post then it is not giving error but adding empty value data in database and it also doesn't support media type json. Now I think that most probably the problem is in the URI and http request.
Here is my github repo of the project : https://github.com/Bk073/Shopping
From this amount of information (no logs) it seems there must be something wrong with JDBC. If everything has been set as default, then I suppose that the id must be auto increment and sending it a null without catching any exceptions just might be the cause... try to omit id from your product object (json) and see what happens...

$http patch method returns bad request in Spring MVC

I'm using angularJS and Spring MVC, and I can't the PATCH request I want to, when I try the response is a Bad Request.
SpringController:
#RestController
#RequestMapping("api/patients")
public class PatientController {
private class PatientRace {
private String race;
}
#RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
public void updatePatientRace(#PathVariable int id, #RequestBody PatientRace patientRace) {
System.out.println(id + ", " + patientRace.race);
}
}
Request being made in AngularJS using $http module:
$http.patch(href, {race: 'Something'})
.then(function(response) {
// DO SOMETHING
});
If anyone could help me I would be really thankfull.
Thank you

Spring MVC 3.2 Backbone.js Post

I'm working on a Google App engine web application with Backbone.js and Spring mvc. I have the following backbone.js code:
var PostModel = Backbone.Model.extend({
defaults: {
"title": "",
"postTxt": ""
}
});
var PostCollection = Backbone.Collection.extend({
url: '/createUserPost',
model: PostModel
});
var postcollection = new PostCollection();
function createPost() {
var postview = new PostView();
postcollection.create({ title: $('#title').val(), postTxt: $('#postTxt').val() });
title: $('#title').val('');
post: $('#postTxt').val('');
}
Spring mvc 3.2 code on the backend:
#RequestMapping(value = "/createUserPost", method=RequestMethod.POST)
public #ResponseBody UserPosts createUserPost( #ModelAttribute(value="post") UserPosts post,
#CookieValue(value = "sessionId", defaultValue = "null") String sessionId) {
//my custom method to get user name by querying the datastore
String author = getAuthorFromSessionId(sessionId);
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
post.setAuthor(author);
pm.makePersistent(post);
}
finally {
pm.close();
}
return post;
}
When post button is clicked, The text is added to the HTML correctly and POST request is made to the server and the status code is 200 OK.
Spring controller is not able to read the request parameters. Alternatively, I tried using HttpServletRequest and request.getParameter("title") without autobinding, but value returned was still null.
Data sent in the request:
{title: "kdkldklfd", postTxt: "kkfdlksffkl"}
Response received:
{"title":null,"author":"admin","postTxt":null}
#RequestMapping(value = "/createUserPost", method=RequestMethod.POST,
consumes = "application/json", produces = "application/json")
public #ResponseBody UserPosts createUserPost(#RequestBody UserPosts post) {
The #RequestBody annotation should be used in place of #ModelAttribute to read the Request parameters.

Web API 405 Error with $http.post

I'm receiving a 405 error with a POST request using $http.post. What's weird is that I'm using $http.post in another area of my application and it works just fine.
I'm using AngularJS for client side, and Web API for server side. I've posted all relevant information (apart from my web.config) that I can think of. Is there something very obvious I'm missing here?
code below does not work (throws 405)
Here's the api controller method that I'm trying to hit:
public async Task<IHttpActionResult> LinkLogin(string provider)
{
Account user = await _repo.FindByNameAsync(User.Identity.Name);
if (user == null)
{
return BadRequest("User does not exist!");
}
return new ChallengeResult(provider, null, "auth/Manage/LinkLoginCallback", user.Id);
}
Here's how I'm trying to hit it on the client side:
var _linkLogin = function (provider) {
$http.post(serviceBase + 'auth/Manage/LinkLogin', provider).then(function (response) {
return response;
});
};
CODE BELOW IS CODE THAT WORKS
Api controller function that works:
// POST auth/Authorization/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(UserModel userModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await _repo.RegisterUser(userModel);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
Calling it from the client side:
var _saveRegistration = function (registration) {
_logOut();
return $http.post(serviceBase + 'auth/Authorization/register', registration).then(function (response) {
return response;
});
};
Here is my web api configuration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "AuthenticationApi",
routeTemplate: "auth/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapODataServiceRoute("ODataRoute", "api", GenerateEdmModel());
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
private static IEdmModel GenerateEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
return builder.GetEdmModel();
}
}
Now I have tried a number of different solutions posted on the web to no avail, the following are links to things I have tried:
Web api not supporting POST method
Web API Put Request generates an Http 405 Method Not Allowed error
http://blog.dontpaniclabs.com/post/2013/01/23/That-Pesky-Requested-Resource-Does-Not-Support-HTTP-Method-POST-Error-When-Using-MVC-Web-API
I hate answering my own question. If anyone else runs into this issue it's because you're trying to send a simple string value to a web api controller.
I used this solution with success: http://jasonwatmore.com/post/2014/04/18/Post-a-simple-string-value-from-AngularJS-to-NET-Web-API.aspx
If the link is dead, you simple wrap the string value in double quotes in your POST request like so:
$http.post(Config.apiUrl + '/processfile', '"' + fileName + '"');

Backbone collection GET works, but PUT and POST both fail

Here is my code for my GET
singleChatModel = new Dashboard.Collections.MessagesCollection();
singleChatModel.fetch({
data:{
userId: userId,
id: chatId
}
});
and here is the C#
[WebGet(UriTemplate = "?userId={userId}&id={id}")]
public MessageServiceModel[] GetAllMessages (string userId, string id)
{
....
}
the request URL
Request URL:http://localhost:1087/apps/messages/Messages/?userId=RJGILL&id=1
That all works great for the get, but I'm having trouble getting into the POST, PUT methods
Here is my POST
newMessage = new Dashboard.Models.MessagesModel;
newMessage.set(messageObj);
newMessage.save({
success: function() {...}
});
and the C#
[WebInvoke(UriTemplate = "?userId={userId}&id={id}", Method = "POST")]
public void AddNewMessage(string userId, string id, string text)
{
...
return;
}
and here is the error that I get
POST http://localhost:1087/apps/messages/Messages/ 400 (Bad Request)
I need to manipulate the URL so that it is matches my UriTemplate.
Can I perform the POST / PUT with the same setup using the 'data' object as I am with the GET?

Resources