I need to call this service in Java -
https://api.semantics3.com/test/v1/products?q={"cat_id": "13658", "brand": "Toshiba", "model": "Satellite"}
I've managed to do this in python as follows -
class Semantics:
def __init__(self):
self.service_address = 'https://api.semantics3.com/test/v1/products?'
self.api_key = 'SEM3158A71D4AB3A3715C2230B96943F46D0'
def query(self, params):
query = 'q=' + params.__dict__.__str__().replace("'",'"')
query = urlencode(urlparse.parse_qs(query), True)
req = Request(url = self.service_address + query)
req.add_header('api_key', self.api_key)
return urlopen(req).read()
class QueryParams:
def __init__(self, cat_id, model, brand):
self.cat_id = cat_id
self.model = model
self.brand = brand
qp = QueryParams('13658', 'Satellite', "Toshiba")
print Semantics().query(qp)
I have tried writing an equivalent Java program using Spring REST API and Apache HttpClient to no avail. I can't find a way to set a dictionary (i.e. Map) into the query String.
public static void main(String[] args) {
String uri = "https://api.semantics3.com/test/v1/products?";
HttpClient hc = new HttpClient();
GetMethod method = new GetMethod(uri);
method.getParams().setParameter("q", "Toshiba");//How do I insert a Map here?
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
method.setRequestHeader("api_key", "SEM2158A71D4AB3A3715C2435B96943F46D0");
try {
int statusCode = hc.executeMethod(method);
System.out.println(statusCode);
byte[] responseBody = method.getResponseBody();
System.out.println(new String(responseBody));
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
method.releaseConnection();
}
}
At the lowest level I can manually produce the query string manually via concatenation and then Url encode it. But is there a more elegant way to do it?
I think you can use external jar like GSON to convert the Map into JSON
Map<String, String> map = new HashMap<String,String>();
map.put("cat_id", "12345");
..
Gson gson = new Gson();
method.getParams().setParameter("q", gson.toJson(map));
Have a look at Google's Http Client
As you can see from the examples, it uses objects to build the request url and deserialise the response body. The docs also show you how to deserialise JSON specifically, and you can choose your JSON library of choice.
Related
I am creating a REST API using Spring Boot and using org.json for parsing data retrieved from another different service. From this service I am getting JSON data like in following format
{
"my_data":[
{
"user_data":{
"first_name":"FirstTest1",
"last_name":"LastTest1",
"age":"25"
}
},
{
"user_data":{
"first_name":"FirstTest2",
"last_name":"LastTest2",
"age":"35"
}
},{
"user_data":{
"first_name":"FirstTest3",
"last_name":"LastTest3",
"age":"45"
}
}
],
"count":10,
"is_safe":false
}
and I have to transform received data to the following JSON
[
{
"user_data":{
"first_name":"FirstTest1",
"last_name":"LastTest1",
"age":"25"
}
},
{
"user_data":{
"first_name":"FirstTest2",
"last_name":"LastTest2",
"age":"35"
}
},{
"user_data":{
"first_name":"FirstTest3",
"last_name":"LastTest3",
"age":"45"
}
}
]
I know I can use a POJO to map the data and send it (already doing this) but here the issue is that the data received from another service is not fixed e.g. it may or may mot have "first_name" or may have a different field like "country". So, in this situation I can not make POJO beforehand.
After going through some online resources I made some changes and my POST Controller method looks like this.
#PostMapping(path = "/searchusersdata")
public RETURN_SOMETHING searchUsersData(#RequestBody Map<String, String> searchData) {
List<JSONObject> finalDataCollection = new ArrayList<JSONObject>();
//Making some REST API CALL TO GET 'response' using 'searchData'
String someResponse = response.getBody();
JSONObject object = null;
try {
object = new JSONObject(someResponse);
} catch (JSONException e) {
e.printStackTrace();
}
String my_data= object.get("my_data").toString();
JSONArray intermediateJA = null;
intermediateJA = new JSONArray (my_data);
for(int i = 0; i < intermediateJA.length(); i++) {
JSONObject item = intermediateJA.getJSONObject(i);
if (item.keySet().contains("user_data"))
{
Object value = item.get("user_data");
finalDataCollection.add(new JSONObject(value));
}
}
//WHAT TO RESTURN HERE
}
Now, I don't know what to return hare. For a single JSONObject we can use return new ResponseEntity<>(return_data.toMap(), HttpStatus.OK); but for a collection I don't know. I am open to suggestion if I have to do it in entirely different way. I also know that with gson or jackson it might be easier but I have to use org.json.
instead of List , use JsonArray and use ResponseEntity to return it.
Example
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonArray.put(jsonObject);
return new ResponseEntity( jsonArray.toString(), HttpStatus.OK);
String json = "{\"loginForm\": [{\"formType\": \"questionAndAnswer\",\"id\": 164422,\"row\": [{\"label\": \"What is the name of your state?\",\"field\": [{\"id\":\"SQandA--QUESTION_1-1\",\"value\": \""+answer1+"\"}]},{\"label\": \"What is the name of your first school\",\"field\": [{\"id\":\"SQandA--QUESTION_2-2\",\"value\": \""+answer2+"\"}]}]}],"+dataset+"}";
this json contains questions and answer in it and its hard coded in my code what should i do to dynamically generate it as i want to remove the hard code and call it dynamically.
You can create a class file with your json fields and then convert the class object to json using Jackson apis.
private String getJsonFromJava (Object obj) {
ObjectMapper mapper = new ObjectMapper();
String jsonInString = "";
try {
jsonInString = mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
System.out.println("Unable to parse object to prepare JSON string", e);
}
return jsonInString;
}
You need to write logic to create json using the inputs. If you are creating the json in JS then look at sample code below. Or you can do the same login in server side - java etc?
function createJSON() {
jsonObj = [];
$("input[questions]").each(function() {
var q= $(this).attr("Question");
var ans= $(this).val();
item = {}
item ["question"] = id;
item ["answer"] = ans;
jsonObj.push(item);
});
console.log(jsonObj);
}
I am creating a RESTful web service using java, MySQ, Jersey, and Gson. It works but my only problem is when I run it on the server and go to the localhost site of my project the JSON is all in one line.
This is the output of the JSON on the web.
"[\n{\n\"id\":5,\n\"subject\":\"Math\",\n\"subjectAcronym\":\"MT\",\n\"classNumber\":2550,\n\"className\":\"Linear Algebra\",\n\"unit\": 3,\n\"prerequisite\":true,\n\"corequisite\":false\n}\n]"
This is the class in the code.
#GET
#Path("/Classes")
#Produces("application/json")
public String feed() {
String feeds = null;
try {
ArrayList<ClassList> feedData = null;
ClassManager projectManager = new ClassManager();
feedData = projectManager.GetFeeds();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(feedData));
feeds = gson.toJson(feedData);
}
catch (Exception e) {
System.out.println("Exception Error"); // Console
}
return feeds;
}
The GsonBuilder().setPrettyPrinting() in the code prints out in the console the way I want it to print out in the web.
The output in the console of eclipse.
[
{
"id": 5,
"subject": "Math",
"subjectAcronym": "MT",
"classNumber": 2550,
"className": "Linear Algebra",
"unit": 3,
"prerequisite": true,
"corequisite": false
}
]
I have 2 more classes similar to this one and all show up the same on the web(in a single line). How can make show on the web like a output in the console? Any response is helpful. Thank you.
That's because your JSON is a string because you set your GsonBuilder to pretty print, which adds newlines and formatting and such. You want to write the JSON with no formatting so it is JSON and not a string. You can also pretty print if you wish. I believe this will solve your problem:
#GET
#Path("/Classes")
#Produces("application/json")
public String feed() {
String feeds = null;
try {
ArrayList<ClassList> feedData = null;
ClassManager projectManager = new ClassManager();
feedData = projectManager.GetFeeds();
Gson gson_pretty = new GsonBuilder().setPrettyPrinting().create();
Gson gson = new Gson();
System.out.println(gson_pretty.toJson(feedData));
feeds = gson.toJson(feedData);
}
catch (Exception e) {
System.out.println("Exception Error"); // Console
}
return feeds;
}
Note that on Google Chrome, JSON is represented on one line. Here is an extension to change that. Firefox displays JSON by default like this:
Solr/SolrJ Version: 6.0.0
I've set termvector component in solrconfig.xml, and the request handler is "/tvrh", I test it in the browser and this works. Now I want to use it in solrJ, but it only returns the document. The following is my code:
SolrClient solrClient = new HttpSolrClient("http://localhost:8983/solr/test");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(String.format("id:%s","clueweb12-0000tw-06-17744"));
solrQuery.setRequestHandler("/tvrh");
solrQuery.set("tv", true);
solrQuery.set("tv.all", true);
QueryResponse response = solrClient.query(solrQuery);
SolrDocumentList docs = response.getResults();
for (SolrDocument doc: docs){
for (String key: doc.keySet()){
System.out.println(key);
System.out.println(doc.getFieldValue(key));
}
}
Your question is how to use a non standard request handler in solr.
Be aware that the Term Vector Component belongs to a "non standard" request handler and is not supported from solrj:
https://cwiki.apache.org/confluence/display/solr/The+Term+Vector+Component#TheTermVectorComponent-SolrJandtheTermVectorComponent
You can call "/tvrh" via solrj in a generic mode. You can not use the method SolrClient#query(SolrParams params) for this, because in this case the "request handler" is only send as "qt"-Parameter and will not be part of the url-path (and qt-Parameter is ignored by default).
So please try the method "SolrClient#request" instead.
As #Karsten R says, we could not use SolrClient.query to send request. After I searched a lot and experimented a lot, the following code could work.
SolrClient solrClient = new HttpSolrClient("http://localhost:8983/solr/trecB13");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(String.format("id:%s","clueweb12-0000tw-06-17744"));
solrQuery.setRequestHandler("/tvrh");
solrQuery.set("tv", true);
solrQuery.set("tv.all", true);
try {
NamedList<Object> response = solrClient.request(new QueryRequest(solrQuery));
TermVectorExtractor extractor = new TermVectorExtractor(response);
System.out.println(extractor.getTermVectorInfo());
} catch (Exception e) {
e.printStackTrace();
}
TermVectorExtractor.java reference Sakai-Solr Github code, the function of the class is to parse resonse object and get term info. A little different from original code. The different has been shown below.
import org.apache.solr.common.util.NamedList;
import java.util.*;
public class TermVectorExtractor {
private static final String TERM_VECTORS = "termVectors";
private Map<String, Map<String, Map<String, TermInfo>>> termVectorInfo = Collections.emptyMap();
/**
* Creates a TermVectorExtractor for the given query response sent by Solr.
*
* #param queryResponse response sent by the solr server for a search query.
*/
#SuppressWarnings("unchecked")
public TermVectorExtractor(NamedList<Object> queryResponse) {
NamedList<Object> res = (NamedList<Object>) queryResponse.get(TERM_VECTORS);
if (res != null)
termVectorInfo = extractTermVectorInfo(res);
}
}
I create a java URL class which contain my Json data and have some function to obtain back my json data for doing some data comparison, I found out it's might not support by JSONObject for passing the data into the JSONObject. Do I need to use JSONArray in my case because my JSON data have array structure as well?
try
{
JSONObject obj = new JSONObject ();
obj.readJsonFromUrl(theUrl);
System.out.println(obj.toString());
}
catch(MalformedURLException e)
{
System.out.print("your problem here ...1");
}
}
else
{
System.out.print("Can't Connect");
}
I am sure that this is the place give me the error message because it return me this error in my compiler
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method readJsonFromUrl(URL) is undefined for the type JSONObject
there are also some warning message for that the JSONObject readJsonFromUrl method
private static JSONObject readJsonFromUrl(URL theUrl) throws IOException, JSONException {
Anyone can provide me the explaination of how the JSON data work in java? I saw quite number of Java class for JSON which make me confuse for it such as JSONObject, JSONArray , JSONValue. I search some information online but I also not very clear about it since I am very new to JSON data processing This is my sample json data and the data I need is scan_result only
{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"file_info":{
"display_name":"",
"file_size":242,
"file_type":"Not available",
"file_type_description":"Not available",
"md5":"aa69ba384f22d0dc0551ace2fbb9ad55",
"sha1":"09ceb54e65df3d3086b222e8643acffe451a6e8a",
"sha256":"dcb46d6ae2a187f789c12f19c44bbe4b9a43bd200a3b306d5e9c1fcf811dc430",
"upload_timestamp":"2016-11-18T09:09:08.390Z"
},
"process_info":{
"blocked_reason":"",
"file_type_skipped_scan":false,
"post_processing":{
"actions_failed":"",
"actions_ran":"",
"converted_destination":"",
"converted_to":"",
"copy_move_destination":""
},
"profile":"File scan",
"progress_percentage":100,
"result":"Allowed",
"user_agent":""
},
"scan_results":{
"data_id":"a71a3c2588c6472bb4daea41a0b58835",
"progress_percentage":100,
"scan_all_result_a":"No Threat Detected",
"scan_all_result_i":0,
"scan_details":{
"Ahnlab":{
"def_time":"2016-11-08T15:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":1,
"threat_found":""
},
"Avira":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":133,
"threat_found":""
},
"ClamAV":{
"def_time":"2016-11-08T10:28:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":94,
"threat_found":""
},
"ESET":{
"def_time":"2016-11-08T00:00:00.000Z",
"location":"local",
"scan_result_i":0,
"scan_time":38,
"threat_found":""
}
},
"start_time":"2016-11-18T09:09:08.405Z",
"total_avs":4,
"total_time":250
},
"vulnerability_info":{
}
}
As mentioned here, there are many ways to solve this. Either you have to implement the read, parse operations yourself (#Roland Illig 's answer)
//you have to implement the readJSON method
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
Or you could use a library. The most well-known and widely used libraries are jackson and gson.
The big picture is that you try to "map" your json Object to a class.
You have your json file:
{
"id":1,
"name":"eirini",
"hobbies":["music","philosophy","football"]
}
and a class that represents this file and will store the values (depending on the library that you use there might be different requirements, for example getters, setters etc..)
public class Person {
public int id;
public String name;
public List<String> hobbies = new ArrayList<String>();
public String toString() {
return name +" has the id: " + id + " the following hobbies" + hobbies.get(0) + " " + hobbies.get(2);
}
}
Finally in your main method:
public static void main(String[] args) throws IOException, ParseException {
ObjectMapper mapper = new ObjectMapper();
InputStream input = this.getClass().getResourceAsStream(FILE); //read your file. There are many ways to achieve this.
ObjectMapper mapper = new ObjectMapper(); // just need one
Person eirini = mapper.readValue(input, Person.class);
System.out.println(eirini.toString());
You cannot pass json in url, you can pass it in body. Writing Json to stream body and post it using regular java method.
Here is oracle community url of explanation of your problem.
Required Jar can be downloaded from here.
Test Code Follows:
URL url = new URL("https://graph.facebook.com/search?q=java&type=post");
try (InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("data");
for (JsonObject result : results.getValuesAs(JsonObject.class)){
System.out.print(result.getJsonObject("from").getString("name"));
System.out.print(": ");
System.out.println(result.getString("message", ""));
System.out.println("-----------");
}
}