i have React JS application where i send post request to server with form submission using axios library.
client request:
sendData(data,price) {
axios.post('http://localhost:8080/SampleJavaAPP/UserServer', {
item: data,//these value
price:price//these value
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
i am not sure how to get these values into server i am doing in server for getting value like this
String name = request.getParameter("item");
String price = request.getParameter("price");
System.out.println("Result "+name + price);
But it gives null values in server. how to receive these values parameters in server?
As Axios is sending Json data you will not be able to read its direct.
There are 2 possible solutions:
Either send data as form-data.
Read & Parse JSON at servlet:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
} catch (Exception e) { /*report an error*/ }
try {
JSONObject jsonObject = HTTP.toJSONObject(jb.toString());
String price = jsonObject.get("price"); // will return price value.
} catch (JSONException e) {
throw new IOException("Error parsing JSON request string");
}
}
Request Body is not retrieved by request.getParameter(). You need to retrieve it by request.getReader().
String body = IOUtils.toString(request.getReader());
It is suggested to use Apache Commons IO to get Content first. As your request is in JSON format. You can use Jackson to convert the String into Map.
Map<String, String> map = mapper.readValue(body, new TypeReference<Map<String, String>>(){});
System.out.println(map.get("item"));
System.out.println(map.get("price"));
request.getParameter()is referring to URL parameters ->myurl?someparameter=1
By doing request.getParameter("item"), your URL would need to look like http://localhost:8080/SampleJavaAPP/UserServer?item=myitem
What you are actually doing here
sendData(data,price) {
axios.post('http://localhost:8080/SampleJavaAPP/UserServer', {
item: data,//these value
price:price//these value
}
is adding the objects to the request body, which is IMHO correct. There for you won't find any parameters item or price on your server side request object.
What you need to do, is to parse the requests body. With request.getInputStream() you can get the Inputstream. I suggest you use an object mapper which makes that really easy. See Intro to the Jackson ObjectMapper
In your servlet, you do something like this:
ObjectMapper objectMapper = new ObjectMapper();
MyItem myItem = objectMapper.readValue(request.getInputStream(), MyItem.class);
public class MyItem{
String price;
String item;
public void setItem(String item) {
this.item = item;
}
public void setPrice(String price) {
this.price = price;
}
public String getItem() {
return item;
}
public String getPrice() {
return price;
}
}
Related
I'm a .Net guy. I tried to call API and getting data from.
Serialized JSON object using java.. but I'm getting this error.
Expected BEGIN_ARRAY but was BEGIN_OBJECT
In .NET it's really easy to do. but in java, I haven't idea how to do that.
this my model class
public class Dictionary {
#SerializedName("metadata")
#Expose
private Metadata metadata;
#SerializedName("results")
#Expose
private List<Result> results = null;
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
}
And here the my api call
public class Oxford {
public String URL_OXFORD = "https://od-api.oxforddictionaries.com/api/v1/inflections/en/swimming";
public static List<Dictionary> httpGet(String url, String function) {
List<Dictionary> dataFromService = new ArrayList<Dictionary>();
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet request = new HttpGet(url+function);
request.addHeader("content-type", "application/json");
request.addHeader("app_id", "566566");
request.addHeader("app_key", "somekey");
HttpResponse result = httpClient.execute(request);
String json = EntityUtils.toString(result.getEntity(), "UTF-8");
com.google.gson.Gson gson = new com.google.gson.Gson();
Dictionary[] response = gson.fromJson(json, Dictionary[].class);
System.out.println(response.length);
for(Dictionary file : response)
{
dataFromService.add(file);
System.out.println(file.toString());
}
} catch (IOException ex) {
}
return dataFromService;
}
Since the documentation returns one object (starting with {, not a [) you probably need a
Dictionary response
instead of
Dictionary[] response
It is returning one dictionary object, not an array. Checkout the documentation at https://developer.oxforddictionaries.com/documentation
I have recently been setting up mobile apps to work with my meteor server. As a part of this I have to pass the meteor web app data from android. Unfortunately I have been receiving a error that tells me that the java object I am passing "would be serialized to null". How do I prevent this?
JSONObject json = new JSONObject();
try{
json.put("Foo", "1");
json.put("Blah", 0);
}catch (JSONException e){
}
Object[] object = new Object[1];
object[0] = json;
System.out.println(object + ", " + object[0] + ", " + object[0].toString());
mMeteor.call("xxx", object, new ResultListener() {
#Override
public void onSuccess(String result) {
}
#Override
public void onError(String error, String reason, String details) {
}
});
}
#Override
public void onError(String error, String reason, String details) {
}
});
Android/Meteor interface Library function
public void callWithSeed(final String methodName, final String randomSeed, final Object[] params, final ResultListener listener) {
// create a new unique ID for this request
final String callId = uniqueID();
// save a reference to the listener to be executed later
if (listener != null) {
mListeners.put(callId, listener);
}
// send the request
final Map<String, Object> data = new HashMap<String, Object>();
data.put(Protocol.Field.MESSAGE, Protocol.Message.METHOD);
data.put(Protocol.Field.METHOD, methodName);
data.put(Protocol.Field.ID, callId);
if (params != null) {
data.put(Protocol.Field.PARAMS, params);
}
if (randomSeed != null) {
data.put(Protocol.Field.RANDOM_SEED, randomSeed);
}
send(data);
}
I was having this same issue, my first error was passing a CharSequence instead a String as a parameter (your Object[]), and my other error was passing an Object[] as another parameter (I solved this by sending a String instead, like : String.valueOf(your_object_list)) Dont forget to handle this on your server side, you will receive a String instead of an Object.
Convert the JSONArray to List & JSONObject to HashMap and then pass those instead of the raw JSONObject or JSONArray.
You can write a recursive function for the conversion in case of nested JSONObject and JSONArray or can use GSON library for the conversion.
For more details about the conversion, this SO post may be helpful.
So I already succeed with one Json to get it all worked. Now I have another class where I want to get only one attribute. I have now a moviedatabase class (which work with JSON and gets all the information) and now I want to add a Trailer which is from Youtube API. so basically I need it to be added into the same JSON to make it easier for me in the future to get it into a HTML. the only problem is I cant get it work. I get a syntax error JSON when using this method.
EDIT CODE 1.1:
Youtube attribute:
public class FilmAttribut {
private String title = "";
private String release = "";
private int vote = 0;
private String overview = "";
private String poster = "";
private String trailer = "";
// getters + setters stripped
}
Youtube class:
public class Youtube {
FilmAttribut movie = new FilmAttribut();
public void search(String trailer, FilmAttribut in) {
HttpResponse<JsonNode> response;
try {
response = Unirest.get("https://www.googleapis.com/youtube/v3/search?key=[app key here]&part=snippet")
.queryString("q", trailer + " trailer")
.asJson();
JsonNode json = response.getBody();
JSONObject envelope = json.getObject();
JSONArray items = envelope.getJSONArray("items");
in.setTrailer("https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId")); //Gives me error here
}
catch (JSONException e) {
e.printStackTrace();
} catch (UnirestException e) {
e.printStackTrace();
}
return null;
}
}
and main method
public class WebService {
public static void main(String[] args) {
setPort(1337);
Gson gson = new Gson();
Youtube yt = new Youtube();
MovieDataBase mdb = new MovieDataBase();
get("/search/:movie", (req, res) -> {
String titel = req.params(":movie");
FilmAttribut film = mdb.searchMovie(titel);
yt.search(titel, film);
String json = gson.toJson(film);
return json;
});
So I think the problem is that you can't have two gson.toJson(film) + gson.toJson(trailer); Because it makes the JSON twice, where one time is for the film (aka. movie) and then a new json is created with trailer which make the syntax error.
So my real question is, is it possible to have another class like I have now youtube. to send the information to a attribute class where I have all my attributes and then run it in main-method so that I can get all the JSON in one JSON.
If I did understand well what you are asking, yes you can, but I would do something like that instead:
public void search(String trailer, FileAttribut in) {
// fetch the trailer from youtube (NB: you should use getters/setters, not public fields)
in.setTrailer("https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId"));
}
and:
FilmAttribut film = mdb.searchMovie(titel);
yt.search(titel, film); // pass "film" to "fill" its trailer
return gson.toJson(film);
OR
public String search(String trailer) {
// fetch the trailer from youtube
return "https://youtu.be/" + items.getJSONObject(0).getJSONObject("id").getString("videoId");
}
and:
FilmAttribut film = mdb.searchMovie(titel);
film.setTrailer(yt.search(titel));
return gson.toJson(film);
I have an endpoint /test which expects Map :
#POST("/hello")
#PermitAll
public JSONObject test(Map param) throws JsonParseException {
String elementName = param.get("name").toString();
String elem = param.get("elem").toString();
JSONObject json=new JSONObject();
try {
json.put("id",1);
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
And I'm sending asynchronous POST (postin JSON) using AsyncHttpClient:
public static void asyncCallPost(JSONObject jsonData) throws Exception {
AsyncHttpClient client = new AsyncHttpClient();
try {
Response response = client.preparePost(url)
.addHeader("Content-Type", "application/json")
.addHeader("Content-Length", "" + jsonData.length())
.setBody(jsonData.toString()).execute().get();
if (response.getStatusCode() != 200) {
throw new Exception("Error ");
}
} finally {
client.close();
}
}
But I am getting java.lang.NullPointerException.
Is it because I don't pass any Map to /hello? If so how make POST with jsonData as Map to the endpoint?
I cannot tell without further information however I suspect that the following needs to change;
String elementName = param.get("name").toString();
String elem = param.get("elem").toString();
to
String elementName;
if(param.get("name") != null){
elementName = param.get("name").toString();
}
String elem;
if(param.get("elem") != null){
elem = param.get("elem").toString();
}
The reason being the param.get("name") is returning a null which you are attempting to run toString on, hence the null pointer exception.
You're setting a JSON string to the body, that's why the Map is null or empty or full of garbage (I didn't check myself).
The Map is a representation of the key-value pairs that are POSTed. To have the Map non-empty, you would have to post e.g. name=myname&elem=myelement as type application/x-www-form-urlencoded.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I stop HTTP from escaping quotes?
I am creating a JSONObject and sending JSON string to a server in a POST request body.
public String toJson() {
JSONObject filter = new JSONObject();
try {
filter.put("gender", gender.getCode());
filter.put("feature_id", productCategory);
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject filterObject = new JSONObject();
try {
filterObject.put("filter", filter);
} catch (JSONException e) {
e.printStackTrace();
}
return filterObject.toString();
}
So I'm creating a request:
private IJsonExecutorInterface requestExecutorForRelativePathAndParams(String path, WebParams params) throws UnsupportedEncodingException {
HttpPost postRequest = new HttpPost(rootUrl + path);
if(params != null) {
postRequest.setHeader("content-type", params.getContentType());
postRequest.setEntity(params.getFormEntity());
}
// Blah blah
return executor;
}
public IJsonExecutorInterface getProducts(ProductFilter filter, int offset, int limit) throws UnsupportedEncodingException {
WebParams webParams = new WebParams();
webParams.addPair("filter", filter.toJson());
webParams.addPair("offset", String.format("%d", offset));
webParams.addPair("limit", String.format("%d", limit));
return requestExecutorForRelativePathAndParams("products", webParams);
}
// WebParams class
public class WebParams {
private ArrayList<NameValuePair> params;
private String contentType = "application/x-www-form-urlencoded";
public WebParams() {
params = new ArrayList<NameValuePair>();
}
public void addPair(String name, String value) {
params.add(new BasicNameValuePair(name, value));
}
public String getContentType() {
return contentType;
}
public HttpEntity getFormEntity() throws UnsupportedEncodingException {
return new UrlEncodedFormEntity(params);
}
}
I see it in debugger: it's ok.
But on my server I getting something like this:
Array
(
[filter] => {\"gender\":\"w\",\"feature_id\":\"41_7459\"}
[offset] => 0
[limit] => 18
)
The quotes ARE escaped.
I don't want to replace something on the server. replace("\\\"", "\"") in Java doesn't affect on the string.
Looks like your using a UrlEncodedFormEntity, which, according to the docs is 'An entity composed of a list of url-encoded pairs' ([http://developer.android.com/reference/org/apache/http/client/entity/UrlEncodedFormEntity.html]). I've never used this, but it doesn't sound like its what you want, as you are sending data in the post body, not through URL parameters.
I've used the StringEntity class before to send json data via post, although it only encodes a string, not name/value pairs, so you've got to do a bit more work to put the string in a format you want to deal with on your server:
public class WebParams {
private ArrayList<NameValuePair> params;
private String contentType = "application/x-www-form-urlencoded";
public WebParams() {
params = new ArrayList<NameValuePair>();
}
public void addPair(String name, String value) {
params.add(new BasicNameValuePair(name, value));
}
public String getContentType() {
return contentType;
}
public HttpEntity getFormEntity() throws UnsupportedEncodingException {
//TODO: Build a string in what ever format you want.
// This will include the gender & feature_id fields as well as the json
StringBuilder b = new StringBuilder();
for(NameValuePair nvp : params) {
builder.append(nvp.getName()).append('=').append(nvp.getValue()).append(',');
}
//Now that we have a string to send to the server, get your entity!
StringEntity entity = new StringEntity(b.toString());
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
return entity;
}
}
Is there a problem to use simple quotes instead of double quotes? Because I think it would solve your problem.