I'm trying to send a json String from an ajax call to a jersey web service. I've looked at many related questions and articles but I haven't been able to get anything to work. When I watch my calls from fiddler I can see the json in the body but when the method is hit the String is blank. Thanks for any help.
getFile: function() {
var urlXls = 'http://localhost:8080/KodiakWebS/Kodiak/KodiakXls/generateXls';
//var json = '{"xls":[{"name":"Pokemon","row":[{"data":"Lugia"},{"data":"Charzard"}]},{"name":"Types","row":[{"data":"Special"},{"data":"Fire"}]}]}'; //encodeURI();
var json = this.get('tempJSON');
urlXls = urlXls.replace(/\s/g, "");
$.ajax({
url: urlXls,
type: "POST",
data: json,
contentType: 'application/json; charset=utf-8', // ;charset=utf-8',
success: function(json, status)
window.location.assign(json.url);
alert("yay");
},
error: function(xhr, err) {
debugger;
alert(xhr+ " || " + err);
}
});
},
#POST
#Path("/generateXls")
#Consumes("application/json")
#Produces({ "application/xls" })
public Response sendWorkBook(final String json) throws Exception {
createWorkbook(json);
FileOutputStream sprdSht = new FileOutputStream("WorkBook.xls");
wb.write(sprdSht);
sprdSht.close();
System.out.println("all done");
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream outPut)
throws IOException,
WebApplicationException {
try {
wb.write(outPut);
} catch (Exception e) {
throw new WebApplicationException(e);
}
}
};
return Response.ok(stream).header("content-disposition", "attachment; filename = egisDoc.xls").build();
}
If you say you consume application/json, then I think you need to provide a Java object to model the JSON you are supplying.
If you do just want the JSON as a String, then you need to consume text/plain.
I typically have this when I use JAXRS:
#PUT
#Path("entities")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public SomeDomainObject updateSomeEntity(SomeDomainObject someDomainObject) {
// Whatever...
}
Where "SomeDomainObject" is just a POJO with getters and setters.
I normally use the JacksonJsonProvider implementation rather than the JAXB one, and the above style of controller works just fine with JSON marshalling for me. I don't even need to add any JSON annotations to the domain objects either.
I was able to get it working thanks to the suggestions from caprica and tinkering around a little bit. Not much changed in my code but here it is.
#PUT
#Path("/generateXls")
#Consumes("text/plain")
#Produces({ "application/xls" })
public Response sendWorkBook(String json) throws Exception {
System.out.println("json: " + json);
createWorkbook(json);
getFile: function() {
var urlXls = 'http://localhost:8080/KodiakWebS/Kodiak/KodiakXls/generateXls';
//var json = '{"xls":[{"name":"Pokemon","row":[{"data":"Lugia"},{"data":"Charzard"}]},{"name":"Types","row":[{"data":"Special"},{"data":"Fire"}]}]}'; //encodeURI();
var json = this.get('tempJSON');
urlXls = urlXls.replace(/\s/g, "");
$.ajax({
type: "PUT",
url: urlXls,
data: json,
contentType: 'text/plain; charset=utf-8', // ;charset=utf-8',
success: function(json, status) {
window.location.href = json.url;
//window.location.assign(json.url);
//alert("yay");
},
error: function(xhr, err) {
debugger;
alert(xhr+ " || " + err);
}
});
},
now on to trying to download xls file my service creates, hopefully I won't need to ask how to get what I have working (but if anyone has a method they're proud of and would like to share you're more than welcome too).
Thanks for the help.
Related
I'm trying to develop a small application to create index on local elasticsearch engine. I use angularjs on the front-end, and spring-boot on the back-end. It can create index successfully, however, when I want to retrive the response in the front-end, it keeps throwing me errors.
Below is my AngularJS api call:
app.service('ESIndexService', function($http) {
this.createESIndex = function(esindexObj) {
var settings = {
method: 'POST',
url: BASE_URL + "/ESIndex/createESIndex",
data: esindexObj
};
return $http(settings).then(function(response) {
console.log("response:"+response);
return response;
}, function(error) {
console.log("error:"+error);
return error;
});
};
});
Then this is my controller:
#CrossOrigin
#RestController
#RequestMapping(value = "ESIndex")
public class ESIndexController {
#RequestMapping(value = "createESIndex", method = RequestMethod.POST)
public #ResponseBody String createIndex(#RequestBody ESIndex esIndex) {
try {
Settings settings = Settings.builder()
.put("xpack.security.user", String.format("%s:%s", Constants.ES_UNAME, Constants.ES_PWD)).build();
TransportClient client = new PreBuiltXPackTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(Constants.ES_HOST), Constants.ES_PORT));
CreateIndexResponse response = client.admin().indices().prepareCreate(esIndex.getName()).setSettings(Settings.builder()
.put("index.number_of_shards", esIndex.getNumberOfShards())
.put("index.number_of_replicas", esIndex.getNumberOfReplicas())).get();
client.close();
if(response.isAcknowledged() && response.isShardsAcked())
return Constants.SUCCESS;
else
return "Fail to create index!";
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
}
I want to get the response status and data in AngularJS response. However, it keeps throwing me errors:
error:SyntaxError: Unexpected token i in JSON at position 0
I'm not using JSON.parse function, why it gives me error like this?
After adding responseType: 'text', still throwing same error, the chrome nextwork
It turns out I need to add "transformResponse: undefined", however, in another of my project, I never did this. What's the difference?
AngularJS:
this.newBlog = function(blogObj) {
var settings = {
method: 'POST',
url: baseUrl + "/blog/newBlog.do",
data: blogObj
}
return $http(settings).then(function(response) {
return response;
}, function(error) {
return error;
});
};
Java Controller:
#RequestMapping(value="newBlog.do", method=RequestMethod.POST)
public #ResponseBody String newBlog(#RequestBody Blog blog, HttpServletRequest request) {
User createdBy = (User) request.getSession().getAttribute("user");
if(createdBy == null)
return NO_SESSION_MSG;
else {
createdBy.setPwd(null);
blog.setCreatedAt(TQBUtilities.getCurrentTime());
blog.setLastUpdatedAt(TQBUtilities.getCurrentTime());
blog.setCreatedBy(createdBy);
return blogService.newBlog(blog);
}
}
Angular is automatically trying to parse the server response as JSON. Try adding this to your settings object
responseType: 'text'
So
var settings = {
method: 'POST',
url: BASE_URL + "/ESIndex/createESIndex",
data: esindexObj,
responseType: 'text'
};
#jheimbouch add "transformResponse: undefined" to http call, like below, works fine:
var settings = {
method: 'POST',
url: BASE_URL + "/ESIndex/createESIndex",
data: esindexObj,
transformResponse: undefined
};
However, why it is required in angularjs 1.6.2? When I was using AngularJS 1.4.8, I don't need to add transformResponse attributes.
I'm currently developing spring mvc application and I need to post JSON array.
When I access request.getParameter("paramValue") to fetch the param attibute, but it returning a null value,
Here is my front-end code:
$.ajax(url, {
async: true,
type: 'post',
contentType: 'application/json',
data: JSON.stringify({
"test":"test value"
})
}).done(function (response) {
console.log(data);
}).fail(function (xhr) {
console.log("request failed");
console.log(xhr);
});
Here is my server-side code:
#RequestMapping(value = "/Products", method = RequestMethod.POST)
public void saveProducts(HttpServletRequest req, HttpServletResponse res) throws Exception {
System.out.println(req.getContentType());
System.out.println(req.getContentLength());
System.out.println(req.getContextPath());
System.out.println(req.getParameterValues("test"));
System.out.println(req.getMethod());
StringBuilder buffer = new StringBuilder();
BufferedReader reader = req.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String data = buffer.toString();
System.out.println(data);
System.out.println(req.getParameter("test"));
}
The output is:
application/json
22
null
POST
{"test" : "Test DAta"}
null
I can't figure out whats going on, please help me.
remove this line in you ajax function
contentType: 'application/json',
and replace this line
data: JSON.stringify({
"test":"test value"
})
with
data: {
"test":"test value"
}
and also you can use
req.getParameter("test")
instead
req.getParameterValues("test")
You can by using this :
var data ={id: 1, name :'test'}
$.ajax(url, {
async: true,
type: 'post',
contentType: 'application/json',
data: data
}).done(function (response) {
console.log(data);
}).fail(function (xhr) {
console.log("request failed");
console.log(xhr);
});
and in server side
create a pojo :
public class Product{
private long id;
private String name;
// getters and setters
add library jackson .
add this method in your controller:
#RequestMapping(value = "/Products", method = RequestMethod.POST)
public RepsoneEntity<? >saveProducts(#requestBody Product pr){
LOG.debug(pr.toString());
return new reRepsoneEntity<Product>(pr,HttpStatus.ACCEPTED);
}
i finally fixed it several annotation and changing the the return type of server side method,
#RequestMapping(value = "/Products", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public ResponseEntity<?> saveProducts(#RequestParam(value = "data") String brand) {
return ResponseEntity.ok(brand);
}</code>
front end
$.ajax(url, {
async: true,
type: "POST",
data: {"data" : JSON.stringify({"Brand" : "Test Brand"})}
}).done(function (response) {
console.log(response);
}).fail(function (xhr) {
console.log("request failed");
console.log(xhr);
});
and i used org.json to access json objects parsed as text, gson to deal with POJOs
and now it works :)
I have a Spring MVC controller being called by AJAX and returns JSON. If the call succeeds without error, I am returning a string message with the key "message". Likewise, if an exception is caught, I return a string error also with the key "message". I also return a HTTP error response.
In my Javascript, I output this "message" in an alert. The alert displays the message in the event of a successful call. If the call is unsuccessful, I get a Javascript error that "data is undefined".
Why is "data" accessible when successful but not when the call fails, and what correction do I need to make this work?
I am a newbie to AJAX calls with Spring so any general feedback/critique of my solution below is welcome and appreciated.
N.B. The alerts in the Javascript and the messages themselves are dummy implementations until I correctly provide user feedback by modifying the DOM.
The Controller
#RequestMapping(value = "/getMovieData", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public Map<String, Object> getMovieData(#RequestBody Map<String, Object> json, HttpServletResponse response) {
String movieId = json.get("id").toString();
Map<String, Object> rval = new HashMap<String, Object>();
try {
Movie movie = movieService.getMovieData(movieId);
rval.put("message", "You have succeeded");
rval.put("movie", movie);
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
rval.put("message", "You have an error - " + e.getMessage());
}
return rval;
}
The Javascipt
function getMovieData(data) {
var request = $.ajax({
type : 'POST',
url : '<c:url value="/getMovieData" />',
dataType : "json",
contentType : "application/json; charset=utf-8",
data : data,
});
request.done(function(data) {
alert("Success: " + data.message);
populateMovieFields(data.movie);
});
request.fail(function(xhr, status, error, data) {
alert("status: " + status);
alert("error: " + error);
alert("Fail: " + data.message);
});
}
The JSON response is available inside the jqXHR object passed as the first parameter.
request.fail(function(jqXHR, textStatus, errorThrown) {
alert("Fail: " + jqXHR.responseJSON.message);
});
I am using spring mvc. I need to pass a json object from my jsp page to controller.
My ajax code:
function createJSON() {
jsonObj = [];
item = {};
$(".values").each(function() {
var code = $(this).attr('id');
item[code] = $('#' + code).val();
});
var content=JSON.stringify(item)
$.ajax({
type: 'POST',
contentType : 'application/json; charset=utf-8',
url: "/pms/season/submit",
data: content,
dataType: "json",
success : function(data) {
alert(response);
},
error : function(e) {
alert('Error: ' + e);
}
});
}
My controller code:
#RequestMapping(value = "/submit", method = RequestMethod.POST)
public void saveNewUsers( #RequestParam ("json") String json) {
System.out.println( "json ::::"+json );
}
But it's not working.
#RequestParam("json") means that you are intending to include a request parameter called json in the URI, i.e. /submit?json=...
I think you intend to get the request body, i.e. #RequestBody.
I would then suggest that, unless you really need the raw JSON string, you would have the #RequestBody translated to a Java object for you:
public void saveNewUsers(#RequestBody MyDto myDto) {
...
}
where MyDto would have getters/setters and fields matching the JSON class.
You can over omit the #RequestBody annotation if you annotate the controller with #RestController, instead of #Controller.
If you definitely want the raw JSON string, then take a look at this previous question: Return literal JSON strings in spring mvc #ResponseBody
After browsing thru SO, i found this piece of code everywhere, even I want to implement AutoComplete, I am using Solr to implement search, and wanted to use TermsComponent foe implementing Autocomplet
var cache = {};
$("#textbox").autocomplete({
source: function(request, response) {
if (request.term in cache) {
response($.map(cache[request.term].d, function(item) {
return { value: item.value, id: item.id }
}))
return;
}
$.ajax({
url: "/Services/AutoCompleteService.asmx/GetEmployees", /* I use a web service */
data: "{ 'term': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function(data) { return data; },
success: function(data) {
cache[request.term] = data;
response($.map(data.d, function(item) {
return {
value: item.value,
id: item.id
}
}))
},
error: HandleAjaxError // custom method
});
},
minLength: 3,
select: function(event, ui) {
if (ui.item) {
formatAutoComplete(ui.item); // custom method
}
}
});
Now my question is, How to configure the url source, wat it should be, the following url
http://localhost:8983/solr/terms?terms.fl=name&terms.prefix=at&wt=json&omitHeader=true
gives me perfect result, now pls tell me wat should be my url source, and if i want to customize add more parameters like terms.lower=py&terms.lower.incl=false&indent=true&wt=json etc ,should i better harcode them in url or in my java class like
List terms = query(q, Integer.parseInt(limit));
private List<TermsResponse.Term> query(String q, int limit) {
List<TermsResponse.Term> items = null;
SolrQuery query = new SolrQuery();
query.addTermsField("spell");
query.setTerms(true);
query.setTermsLimit(limit);
query.setTermsLower(q);
query.setTermsPrefix(q);
query.setQueryType("/terms");
try {
QueryResponse qr = server.query(query);
TermsResponse resp = qr.getTermsResponse();
items = resp.getTerms("name");
} catch (SolrServerException e) {
items = null;
}
return items;
}
Please help, um not so good in jquery, so wanted to confirm one more thing,for wat i need, i just need to modify the url over here or have to customize few more things
It's not very likely that you need to parameterize this client-side, so set those parameters server-side. Setting them with code instead of hardcoding them in the URL is generally better, it reveals the intention. Also remember that you can set parameters in the solr config.
Lastly, don't program by coincidence. Understand the jQuery snippet you're using, otherwise you will have problems sooner or later.