how to call spring mvc3 with jquery ajax post between two applications? - java

I have two web applications hosted on a server. From one I am trying to do $.post to the second application (spring mvc3). I am able to successfully hit the url of the second application but I do not get response back of the ajax call.
App1 JS Code (http://localhost:7777/app1/test.html) -
var serialisedFormData = $("form").serialize();
$.post("http://localhost:8080/app2/doSomething", serialisedFormData, function (data) {
alert("job done");
}, "json");
App2 Java Code -
#RequestMapping(value = "/doSomething")
public #ResponseBody String doSomething(HttpServletRequest request,
#RequestParam("d") String data) {
try {
... do something here ...
return "done";
}
catch (Exception e) {
logger.debug("Exception occured when doing something", e);
return "failure";
}
}

I achieved it by removing "json" type from my jquery post call.
$.post("http://localhost:8080/app2/doSomething", serialisedFormData, function (data) {
alert("job done");
});
and adding a header to my response
#RequestMapping(value = "/doSomething")
public #ResponseBody String doSomething(HttpServletRequest request, HttpServletResponse response, #RequestParam("d") String data)
{
try {
... do something here ...
response.setHeader("Access-Control-Allow-Origin", "*");
return "done";
}
catch (Exception e) {
logger.debug("Exception occured when doing something", e);
return "failure";
}
}

Related

#POST Method REST - Status Code: 405 / Method Not Allowed

#POST Method REST - Status Code: 405 / Method Not Allowed
I am invoking a REST method from JSP which results in error Status Code: 405 / Method Not Allowed
What could be the reason and how can resolve the issue? Application server Weblogic 12.2.1.4
#POST
public Object saveProduct(#FormParam("productId") String productId,
#FormParam("productCategoryId") #Context HttpServletRequest request,
#Context HttpHeaders headers) {
String returnJSON = null;
List<ProductList> productPersistList = new ArrayList<ProductList>();
ProductPersist productPersist = new ProductPersist();
productPersistList.add(productPersist);
log.info("productId " + productId);
try {
for (ProductList persistItems: productPersistList) {
persistItems.setProductId(productId);
}
productPersistDAO.persistData(productPersistList);
log.info("persist data ");
map.put("success", "true");
map.put("msg", "Done");
returnJSON = JSONObject.fromObject(map).toString();
} catch (Exception e) {
log.error("error from persistData " + e);
e.printStackTrace();
} finally {
map.clear();
}
return returnJSON;
}
Update 1
The below is the code snippet where REST API is called wher it is defined in a .js file
function saveProduct(param){
$('#fmEdit').form('submit',{
method: 'POST',
contentType : "application/x-www-form-urlencoded",
url: url,
onSubmit: function(){
return $(this).form('validate');
},
success: function(result){
var result = eval('('+result+')');
if (result.errorMsg){
$.messager.show({
title: 'Error',
msg: result.errorMsg
});
} else {
successMessage();
$('#dg').datagrid('reload');
if(param=='saveclose' ){
$('#dlg').dialog('close');
}
else if(param == 'save'){
$('#fmEdit').form('clear');
}
}
}
});
}
have u tried to set Consumes(MediaType.APPLICATION_FORM_URLENCODED) in the REST service method?

Access JSON response from RequestBuilder

Might be a dumb question but how can I retrieve the value of the response given by the RequestBuilder in a JSON format. My code is this:
try {
Request request = builder.sendRequest(json, new RequestCallback() {
public void onError(Request request, Throwable exception) {
System.out.println("CAN'T CONNECT");
// Couldn't connect to server (could be timeout, SOP violation, etc.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
System.out.println("SUCCESS");
System.out.println(response.getText());
// Process the response in response.getText()
} else {
System.out.println("ERROR" + response.getStatusCode() + response.getText());
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
System.out.println(e);
}
Currently, the response gives me {faceAmount: 29921}. How do I access the value for faceAmount and store it to a variable? Is the response providing me with a JSON format or just straight up text string?
You can use com.google.gwt.json.client, or use JSNI and overlay types, or better, use JsInterop. You'll find more in the docs: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSON.html, http://www.gwtproject.org/doc/latest/tutorial/JSON.html, http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html
#JsType(isNative=true)
interface Response {
#JsProperty int getFaceAmount();
}
Response r = (Response) (JavaScriptObject) JsonUtils.parse(json);

Sending the object in ajax call to spring controller and getting unsupported media type message

I have an ajax call like this
var userList = {
"active": activeUsersId,
"inactive": inactiveUsersId
}
$.ajax({
type: "POST",
data: userList,
url: "/ewaanmapbuilder/rest/user/status",
contentType: "application/json",
success: function (flag) {
if (flag == true) {
$("#messageContainer").text("Status Updated Successfully!");
}
else {
$("#messageContainer").text("Status Updation Failed!");
}
$('#messageContainer').css('display', 'block');
setTimeout(function () { $('#messageContainer').css('display', 'none'); $('.registration-container').css('margin-top', '10%') }, 3000);
}
});
In this ajax call i am sending the userlist as aobject and my spring controller is like this
#ResponseBody
#RequestMapping(value = EwaanMapBuilderConstant.UPDATE_USER_STATUS, method = RequestMethod.POST,consumes= MediaType.APPLICATION_JSON_VALUE)
public boolean updateUserStatus(#RequestBody ActiveUserList userList, HttpServletRequest request) {
try {
HttpSession session = request.getSession();
String adminUserId = session.getAttribute(EwaanMapBuilderConstant.USER_ID).toString();
userService.updateUserStatus(userList, adminUserId);
}
catch(Exception e) {
logger.error("update status failed" +e);
return false;
}
return true;
}
BUt my ajax call gives me "415 (Unsupported Media Type)" error. I have tried so many options but i am not getting where i am going wrong.

Angularjs - Spring MVC Rest : how to handle exceptions

I am developping an single page app with angularjs and Spring Mcv Rest.
I am calling my service (mail sending with javax mail) like that in Angularjs : SendProformaFax.get({idCommande:$scope.commande.id})
And on server side my service :
#RequestMapping(value = "/sendProformaFax/{idCommande}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public void imprimeProforma(#PathVariable String idCommande) {
Commande commande = commandeRepository.findOne(new Long(idCommande));
List<Vente> ventes = venteRepository.findAllByCommande(commande);
blService.sendProformaFax(ventes);
}
I would like to display a message when the function sendProformaFax throws a MessagingException.
I don't know how to return this exception in my RestController and how to catch it in Angularjs.
If anyone can help me on this...
Thanks.
EDIT :
On server side I am doing this :
#ExceptionHandler(value = Exception.class)
public ErrorView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
// If the exception is annotated with #ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
throw e;
// Otherwise setup and send the user to a default error-view.
ErrorView mav = new ErrorView();
mav.setException(e.getMessage());
mav.setUrl(req.getRequestURL().toString());
mav.setMessage("Veuillez contacter le support informatique.");
return mav;
}
On Angularjs side I am doing this
CreateFichierCiel.get({params:param}, function (response) {
$scope.infoMessage = "La génération du fichier CIEL est terminée."
$activityIndicator.stopAnimating();
$("#messageModal").modal('show');
$scope.find();
}, function (reason) {
$("#errorModal").modal('show');
})
But 'reason' object is like this :
config: Object data: Object error: "Internal Server Error" exception:
"java.lang.NullPointerException" message: "No message available" path:
"/api/createFichierCiel/15-00005" status: 500 timestamp: 1438430232307
proto: Object headers: function (name) { status: 500 statusText:
"Internal Server Error" proto: Object
So I am not getting the ErrorView class sent from the server.
If anyone can see where I am wrong here...
Thanks
You can make ExceptionHandler for MessagingException and set HTTPStatus to indicate that response has an error (egz. BAD_REQUEST)
#ExceptionHandler(MessagingException.class)
#ResponseStatus(HTTPStatus.BAD_REQUEST)
#ResponseBody
public ErrorView handleMessagingException(MessagingException ex) {
// do something with exception and return view
}
In AngularJS you can catch it from resource service like this:
MessagingService.get({idCommande: 1}, function (data) {
// this is success
}, function (reason) {
// this is failure, you can check if this is a BAD_REQUEST and parse response from exception handler
};
It almost the same when you use $http.
Adding to the answer by kTT, starting with Spring 4 you can wrap your #ExceptionHandler method in a class annotated with #ControllerAdvice so that you will have the same message for the same type of exception across the whole application. More you can look here
That is how I did it, we are using spring mvc and angularjs in our project.
I have this controllerAdvice class
#ControllerAdvice
public class ExceptionControllerAdvice {
#ExceptionHandler(ServiceException.class)
public ResponseEntity<ErrorResponse> rulesForCustomerNotFound(HttpServletRequest req, ServiceException e)
{
ErrorResponse error = new ErrorResponse();
error.portalErrorCode = e.getExceptionCode();
error.message = e.getMessage();
return new ResponseEntity<ErrorResponse>(error, HttpStatus.NOT_FOUND);
}
}
class ErrorResponse {
public int portalErrorCode;
public String message;
}
and then in restful controller where ServiceException is a customized runnable exception:
#Override
#RequestMapping("/getControls/{entity}")
public List<Control> getControls(#PathVariable(value="entity") String entity) throws ServiceException {
List<Control> controls = ImmutableList.of();
try {
controls = dao.selectControls(entity);
} catch (Exception e) {
logger.error("getting list of controls encountered an error ", e);
throw new ServiceException(50, "getting list of controls encountered an error.");
}
return controls;
}
in my app.js file in angularjs I use
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(function ($q, $location) {
return {
'response': function (response) {
//Will only be called for HTTP up to 300
return response;
},
'responseError': function (rejection) {
if(rejection.status === 0) {
alert('There is a problem connecting to the server. Is the server probably down?!');
}
else {
$location.url('/error').search({rejection: rejection});
}
return $q.reject(rejection);
}
};
});
}])
and in a error.controller.js
function init() {
ctrl.rejection = $location.search().rejection;
ctrl.portalErrorCode = ctrl.rejection.data.portalErrorCode;
ctrl.errorMessage = ctrl.rejection.data.message;
$log.info('An error occured while trying to make an ajax call' + ctrl.errorMessage + ': ' + ctrl.portalErrorCode);
}
and of course in error.tpl.html
<h2>
{{ctrl.rejection.status}} {{ctrl.rejection.statusText}}
</h2>
<h3 class="error-details">
Sorry, an error has occurred!
</h3>
<h3 class="error-details">
{{ctrl.errorMessage}}
</h3>

Error 405 Method Not Allowed error, when sending DELETE to server

I get following response when I try to delete: 405 Method Not Allowed.
In my logs there is written that GET is allowed, but DELETE isn't.
Java:
#ResponseBody
#RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void delete(#PathVariable String id) {
speakerService.delete(id);
}
Angularjs
app.factory('SpeakerResource', function ($resource) {
return $resource('rest/speaker/:speakerId',
{
speakerId: '#speakerId'
},
{
'update': { method: 'PUT' }
},
{
'delete': { method: 'DELETE', params: { 'id': 'speakerId' }}
}
)
});
SpeakerService
this.delete = function (id, callback) {
SpeakerResource.delete({ speakerId: id }, function () {
callback();
});
}
I do not know your complete code, and I am not an expert in AngularJS, but it looks like your want to send a DELETE request to the URL <hopefullySomething>/{id} (Path variable). But it looks like that you send a DELETE request so some URL with an parameter id <hopefullySomething>?id={id} (Request parameter).
This question and answers explain the difference between path variable and request parameters a bit more #RequestParam vs #PathVariable
use $http.delete(), and return data for example status, I just tested the following with spring and working correctly
#RequestMapping(value = "delete/{id}", method = RequestMethod.DELETE)
public #ResponseBody Status deletePerson(#PathVariable("id") int id) {
try {
personService.removePerson(id);
return new Status(1, "person deleted Successfully !");
} catch (Exception e) {
return new Status(0, e.toString());
}
}
angular
angular.module('personService', [])
.factory('Person', ['$http',function($http) {
return {
deletePerson: function(id) {
return $http.delete('/restperson/delete/'+id);
}
}
}]);
controller
angular.module('personController', [])
// inject the person service factory into our controller
.controller('mainController', ['$scope','$http','Person', function($scope, $http, Person) {
//delete
$scope.deletePerson = function(id) {
Person.deletePerson(id)
.success(function(data) {
$scope.message = data;
});
};
}]);

Categories