Error while sending json from angular to spring controller - angularjs

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...

Related

MediaType is always application/json in MessageBodyWriter in Quarkus with quarkus-resteasy-reactive

Im migrating a JAX-RS application to Quarkus using the resteasy-reactive-jackson extension. One of the resource methods should return an Excel document if the Accept-header is application/vnd.ms-excel. The Excel document is created in a MessageBodyWriter<>. This works as expected in the old application (KumuluzEE, Jersey).
My requests are successfully routed to the resource method, the Accept-header is present but when the response entity arrives at my implementation of isWriteable in the MessageBodyWriter<> the mediaType parameter is always application/json. I have tried implementing a ServerMessageBodyWriter<> but that did not make any difference.
Any ideas of whats going on?
Im using Quarkus v2.2.
Edit 2:
The service interface is in it's own Maven module:
#Path("")
#Produces(MediaType.APPLICATION_JSON)
#RegisterRestClient
#RegisterClientHeaders
public interface MyResource {
#GET
#Path("{id}")
// #Produces({"application/vnd.ms-excel", MediaType.APPLICATION_JSON}) // Works
#Produces({MediaType.APPLICATION_JSON, "application/vnd.ms-excel"}) // Does not work
Response getData(#PathParam("id") Long id);
}
The resource implementation and MessageBodyWriter:
public class MyResourceImpl implements MyResource {
#Context
HttpHeaders httpHeaders; // getAcceptableMediaTypes() returns mediatypes
// matching Accept-header as expected
#Override
public Response getData(#PathParam("id") Long id) {
return Response.ok().entity(new MyData()).build();
}
}
#Provider
#Produces({"application/vnd.ms-excel"})
public class ExcelMessageBodyWriter implements MessageBodyWriter<MyData> {
#Override
public boolean isWriteable(Class<?> aClass, Type type,
Annotation[] annotations, MediaType mediaType) {
// mediaType is always MediaType.APPLICATION_JSON_TYPE when JSON
// is listed first in #Produces in service interface
return aClass == MyData.class && mediaType.getType().equals("application")
&& mediaType.getSubtype().equals("vnd.ms-excel");
}
...
}
Changing #Produces({MediaType.APPLICATION_JSON, "application/vnd.ms-excel"}) on the resource method to #Produces({"application/vnd.ms-excel", MediaType.APPLICATION_JSON}) solved my problem. This can't be the expected behaviour?

Passing String from angular to Spring using #Requestbody

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);
}}

$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 websocket MissingSessionUserException: No "user" header in message

I have problem when I try to send message from client to server on Spring websocket.
I have configuration Websocket on server and create #Message on controller.
I send data from client via javascript.
It just work sometimes, but sometimes it fail and throw message on server: MissingSessionUserException: No "user" header in message
Here're my WebsocketConfig:
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connectsocket").withSockJS();
}
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/");
}
}
Here're my MessageController:
#RestController
public class MessageController {
#Autowired
private SimpMessagingTemplate template;
#MessageMapping("/websocket/message")
public synchronized void message(Message<Object> messageObj,
WebMessage message, Principal principal) throws Exception {
if (principal != null) {
String name = principal.getName();
template.convertAndSendToUser(name, "/topic/dynamic", new MessagePojo("stage", "value", "message"));
}
}
}
Here're my Javascript-backbonejs code:
app.Models.WebsocketModel = Backbone.Model.extend({
fetchData : function() {
console.log("WebsocketModel: fetchData");
var socket = new SockJS(url + "/connectsocket");
var client = Stomp.over(socket);
var onConnect = function(frame) {
console.log('Connected: ' + frame);
client.subscribe("/user/topic/dynamic", function(data) {
var jsonBody = JSON.parse(data.body);
console.log(jsonBody);
});
};
client.connect({}, onConnect);
setInterval(function() {
client.send("/websocket/message", {}, JSON.stringify({
"message" : "Hello world!!!",
"toUser" : "Someone"
}));
}, 10000);
}
});
Here're my server error log:
[2016 Apr 14 - 02:13:19] ERROR:
[org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler]
- Unhandled exception org.springframework.messaging.simp.annotation.support.MissingSessionUserException:
No "user" header in message at
org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:42)
at
org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at
org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:139)
at
org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:108)
at
org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:490)
at
org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:497)
at
org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:87)
at
org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:451)
at
org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:389)
at
org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
You are trying to subscribe to a user destination so the user must be authenticated.
If that is an anonymous user who want to subscribe to the topic, answer to this question will help.
You'll have to assign an anonymous identify to the user and there are two options:
Configure a sub-class of DefaultHandshakeHandler that overrides determineUser and assigns some kind of identity to every WebSocketSession.
The WebSocket session will fall back on the value returned from HttpServletRequest.getUserPrincipal on the handshake HTTP request. You could have a servlet Filter wrap the HttpServletRequest and decide what to return from that method. Or if you're using Spring Security which has the AnonymousAuthenticationFilter, override its createAuthentication method.

How to get different JSON content in the same $http.get

I'm using AngularJS to retrieve a list of objects from a Server. The server side is being made with Spring MVC.
So, I'd like to return a list of these objects as JSON format, but, I'd like to return an informative message object if the server coudn't retrieve the data for any reason.
Can I do it without encapsulating the List<> and the Message objects in a DTO (Data Transfer Object)?
How can I check on AngularJS the received JSON if it can be from 2 different types?
Here is a fragment of my controller class. It currently returns a list of the MyType I'd like to return. But the idea is to convert it to a generic type (Object, maybe?) and return from this request the list or the message, depending on the case.
#RequestMapping(value = RestPaths.LIST_MYTYPE_BY_OWNER, method = RequestMethod.GET)
public #ResponseBody List<MyType> listByOwner(#RequestBody Owner o) {
List<MyType> myType = myService.list(o);
return myType;
}
This is the service that consults the controller. How could I treat the data, considering that the JSON could have different formats?
this.listMyType = function(ownerId){
var deferred = $q.defer();
$http.get('/rest/my/list_by_owner',{})
.then(function (response) {
if (response.status == 200) {
deferred.resolve(response.data);
}
else {
deferred.reject('Error retrieving list of myType');
}
});
return deferred.promise;
}
I wouldn't use an exception for flow control. If both cases (list is empty or it is not) are valid, handle both of them in your handler method. Use ResponseEntity to encapsulate your response. Return a String message in one case (empty) and a List<MyType> in the other (not empty).
#RequestMapping(value = RestPaths.LIST_MYTYPE_BY_OWNER, method = RequestMethod.GET)
public ResponseEntity<?> listByOwner(#RequestBody Owner o) {
List<MyType> myType = myService.list(o);
if (myType.isEmpty()) {
return new ResponseEntity<>("The message", HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>(myType, HttpStatus.OK);
}
All handler method return values are handled by HandlerMethodReturnValueHandler objects. The corresponding one for ResponseEntity is HttpEntityMethodProcessor. It handles the ResponseEntity's body the same way #ReponseBody would.
So a String would be written directly to the response as text/plain (or html) and the List<MyType> would be serialized to application/json by default (or whatever you have configured).
You can add response headers to the ResponseEntity which can also help determine how the content will be serialized (content-type, etc.).
My suggestion is to throw an exception, then add in a spring exception handler which sets the appropriate status code and message:
#RequestMapping(value = RestPaths.LIST_MYTYPE_BY_OWNER, method = RequestMethod.GET)
public #ResponseBody List<MyType> listByOwner(#RequestBody Owner o) {
List<MyType> myType = myService.list(o);
if (myType.size() == 0) {
throw new ResourceNotFoundException("List was empty");
}
return myType;
}
and
#ControllerAdvice
public class ControllerExceptionHandler {
#ExceptionHandler(ResourceNotFoundException.class)
public void handleException(Exception e, HttpServletReponse response) {
response.setStatus(HttpStatus.NOT_FOUND);
response.getOutputStream().write(e.message);
}
}
Here is a pretty good write up on spring mvc exception handling: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

Resources