I am using the lightcouch API to connect to couchdb through Java. I am able to save a single document using dbclient.save(object) method. However, my requirement is to save bulk documents at a time. I am not able to find any methods related to saving bulk documents using the Lightcouch api. Please suggest any possible solution.
Thanks in advance!
I decided to give it a go. I have a database holding documents that describe a person.
Here is my Person class which extends Document LightCouch:
public class Person extends Document {
private String firstname = "";
private String lastname = "";
private int age = -1;
public Person(String firstname, String lastname, int age) {
super();
this.setFirstname(firstname);
this.setLastname(lastname);
this.setAge(age);
}
// setters and getters omitted for brevity
}
The algorithm is simple.
Create an array of type Document
Put your documents into the array
Create a HTTP POST request
Put the JSON converted array into the request body
Send it
Here is roughly what the code could look like.
Note: try/catch omitted for brevity! Of course you are expected to use them.
public static void main(String[] args) {
// You could also use a List and then convert it to an array
Document[] docs = new Document[2];
docs[0] = new Person("John", "Smith", 34);
docs[1] = new Person("Jane", "Smith", 30);
DefaultHttpClient httpClient = new DefaultHttpClient();
// Note the _bulk_docs
HttpPost post = new HttpPost("http://127.0.0.1:5984/persons/_bulk_docs");
Gson gson = new Gson();
StringEntity data =
new StringEntity("{ \"docs\": " + gson.toJson(docs) + "}");
data.setContentType("application/json");
post.setEntity(data);
HttpResponse response = httpClient.execute(post);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed. HTTP error code: "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
httpClient.getConnectionManager().shutdown();
}
I'll describe the two noteworthy parts in this example.
First one is the collection of documents. In this case I used an array instead of a List for the example.
Document[] docs = new Document[2];
docs[0] = new Person("John", "Smith", 34);
docs[1] = new Person("Jane", "Smith", 30);
You could use a List as well and later convert it to an array using Java's utility methods.
Second one is the StringEntity. As per CouchDB's documentation on the HTTP Bulk Document API on modify multiple documents with a single request the JSON structure of your request body should look like this.
{
"docs": [
DOCUMENT,
DOCUMENT,
DOCUMENT
]
}
This is the reason for the somewhat ugly StringEntity definition.
StringEntity data = new StringEntity("{ \"docs\": " + gson.toJson(docs) + "}");
As a response you'll get a JSON array containing objects whose fields represent the *_id* and *_rev* of the inserted document along with a transaction status indicator.
I did the same thing but with spring Rest Template
I created a class which would hold the documents to be updated int he following way.
public class BulkUpdateDocument {
private List<Object> docs;
}
My Rest code looks like this.
BulkUpdateDocument doc = new BulkUpdateDocument(ListOfObjects);
Gson gson = new Gson();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<?> requestObject = new HttpEntity<Object>(gson.toJson(doc), header);
ResponseEntity<Object> postForEntity = restTemplate.postForEntity(path + "/_bulk_docs", requestObject, Object.class);
Related
I am working in JAVA 1.8 to write and using Apache Tomcat to run the server, I am unable to retrieve data from a POST request i.e in JSON.
I actually need it in an HashMap and I can even parse and convert it into HashMap even if it is readable in JSON. I have tried several links on the internet and I always get exception like Could not deserialize to type interface PACKAGE NAME.
#POST
#Produces("application/json")
#Consumes("application/json")
#Path("ClassifyCase")
public Rules Classify(HttpServletRequest request) {
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null)
jb.append(line);
} catch (Exception e) { System.out.println("Buffer Reader Error"); }
System.out.println("What I read: "+jb);
System.out.println("Here la la l ala ");
// System.out.println("Case: ++ "+Case.toString());
System.out.println("Here la la l ala ");
Rules foundRule = new Rules();
// List<Rules> objListRules = new ArrayList<Rules>();
try
{
DataAccessInterface objDAInterface = new RuleDataAdapter();
AbstractDataBridge objADBridge = new DatabaseStorage(objDAInterface);
// foundRule = objADBridge.Classify(Case);
logger.info("Classification done!");
}
catch(Exception ex)
{
logger.info("Error in classification");
System.out.println("Couldnt Classify Properly!");
// return
}
return foundRule;
}
Can someone please share a guide on how can I receive this data and convert it into a Map or either I can directly get a Map!
I strongly recommend you to use this library of JSON..
You can find it in Maven Repository and it's so easy to parse a JSON to a Map or to a JSONArray or JSONObject... depends of your necessity what you want to do..
Here is a example show how to parse a JSON to a HashMap
Map<String, Object> map = new JSONObject(--JSONString here--).toMap();
And that's all...
Now, if your JSON has a list of objects, i mean like a list of maps, what you just need to do is this...
JSONArray jsonArray = new JSONArray(--JSON string here--);
for(int i = 0; i < jsonArray.length(); i++){
Map<String, Object> map = jsonArray.getJSONObject(i).toMap();
}
Here is the explanation.
You take you JSON string and pass it as a parameter to the JSONArray,what JSONArray does is, take your json string a parse it to like a list
Then you make a for to get each Object of that list and parse it to a map.
Note: what the JSONObject does, is take the object of the JSONArray and parse it... you can parse it to a map or you can get each object of that map..
String jsonString = "{\n" +
"\t\"1\": \"1\",\n" +
"\t\"FPG\": \"50\",\n" +
"\t\"Symptoms\": \"Yes\"\n" +
"}";
Map<String, String> map = new Gson().fromJson(jsonString, Map.class);
for (String key: map.keySet()) {
System.out.println(map.get(key));
}
The request you send does not contain proper JSON in the body. You are missing the commas ",". It should be something like this:
{
"1":"1",
"FPG":"50",
"Symptoms":"yes"
}
Just change it and give proper JSON format to the message.
Even if the request was not in your control, I would strongly suggest that you contacted the service that creates the message and asked from them to fix it.
It would be the last resort for me to make my own deserializer to handle an "inproper" message.
An easy way to check if your JSON is properly formated is an online formatter, e.g. https://jsonformatter.org/
In Java, is there a way to retrieve a piece of information from a JSON object by index? I am accessing a financial data table on quandl and want to return the most recent mortgage rate posted in the table. The key is the date the rate was posted in string form. The key for the most recent data will change weekly but the data I want will always be the first key-value pair in the table.
I was able to do this in JavaScript in about 5 minutes. But it seems more cumbersome in Java. Below is the iteration of my code that seems to be closest to getting me where I want to go. I am able to return the first key-value pair set in the table as an object in Java, which is ... ["2017-12-14",3.93]. The final step is eluding me. How do I grab the 3.93 and return that? Or is there a better way to go about this?
double baseRate = 0.0;
default double getBaseRate() throws MalformedURLException {
try {
// make a GET request
URL url = new URL("https://www.quandl.com/api/v3/datasets/FMAC/30US.json?api_key=-c-s9zf8s1NdLbhVin1p");
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
InputStreamReader is = new InputStreamReader((InputStream) request.getContent());
// Convert response stream to a JSON object
JsonReader reader = Json.createReader(is);
JsonObject obj = reader.readObject();
reader.close();
request.disconnect();
// Drill down to the desired piece of data
JsonObject dataset = obj.getJsonObject("dataset");
JsonArray data = dataset.getJsonArray("data");
Object currentData = data.get(0);
System.out.println(currentData);
} catch (IOException e) {
e.printStackTrace();
}
return baseRate;
}
I think that you need to go down another level of array to access the value you required.
JsonArray data = dataset.getJsonArray("data");
JsonArray firstPieceOfData = data.get(0);
Object firstRate = firstPieceOfData.get(1);
If you use Jackson for reading your JSON you can use the .at() method which allows you to access the node's value via a JSON Pointer Expression which in your case would be "/dataset/data/0/1"
I've truncated your json for the purpose of this demo:
String jsonString = "{\"dataset\":{\"id\":4644596,\"dataset_code\":\"30US\",\"database_code\":\"FMAC\",\"name\":\"30-Year Fixed Rate Mortgage Average in the United States\",\"description\":\"Units: Percent\\u003cbr\\u003e\\u003cbr\\u003eNot Seasonally Adjusted\",\"refreshed_at\":\"2017-12-18T04:09:32.892Z\",\"newest_available_date\":\"2017-12-14\",\"oldest_available_date\":\"1971-04-02\",\"column_names\":[\"Date\",\"Value\"],\"frequency\":\"weekly\",\"type\":\"Time Series\",\"premium\":false,\"limit\":null,\"transform\":null,\"column_index\":null,\"start_date\":\"1971-04-02\",\"end_date\":\"2017-12-14\",\"data\":[[\"2017-12-14\",3.93],[\"2017-12-07\",3.94],[\"2017-11-30\",3.9]],\"collapse\":null,\"order\":null,\"database_id\":582}}";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNodes = mapper.createObjectNode();
try {
jsonNodes = mapper.readTree(jsonString);
} catch (IOException e) {
//e.printStackTrace();
}
System.out.println(jsonNodes.at("/dataset/data/0/1").asDouble());// 3.93
I am sending a POST request using HTMLUnit that sends keywords as parameters. An example of the URL is:
website.com/foo/bar/api?keywords=word1,word2,word3&language=en
The problem is my application is dynamically picking these words and the amount of words can go up to 10 or 20 or even more. How do you append a Set of words as values to a HTTP request. My code at the moment is:
requestSettings = new WebRequest(new URL("website.com/foo/bar/api?"),
HttpMethod.POST);
Iterator<String> itr = list.iterator();
while(itr.hasNext()) {
requestSettings.getRequestParameters()
.add(new NameValuePair("keywords[]", itr.next()));
}
requestSettings.getRequestParameters().add(new NameValuePair("language", "en"));
System.out.println(requestSettings.getUrl().toString());
response = webClient.getPage(requestSettings).getWebResponse();
This code does not return a valid respone. What am I doing wrong here?
Give this a try:
using (var client = new WebClient())
{
var dataObject = new {
KeyWords = "one, two, three"
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(dataObject);
var response = client.UploadString("yourUrl", json);
}
I am trying to validate this string below. Actually I am receiving this string in my servlet, now I need to validate these values at backend. What is the right way to do so. Shall I first convert it to JSON Object then to HashMap? Please suggest the correct/appropriate approach to be used here. I am quite new to Java and JSON.
String is
"{"if_ack":4},{"if_cmd":1,"if_state":1},{"if_cmd":1,"if_state":5}"
I am using GSON for processing JSON at server. For example:
InputStream is (send by client, JSON format)
Reader reader = new InputStreamReader(is);
Gson gson = new Gson();
List<YourClass> items = gson.fromJson(reader, new TypeToken<List<YourClass>>()
YourClass should have attributes like if_ack, if_state, if_cmd,...
Then you use as simple as this:
for (YourClass item : items) {
//do whatever you want
}
EDIT: your string should be in correct JSON format like this (JSON array): [{"if_ack":4}, {"if_cmd":1,"if_state":1}, {"if_cmd":1,"if_state":5}]
EXAMPLE:
You have JSON like this : [{"id": "1", "image": "test1"}, {"id": "2", "image": "test2"}]
YourClass.java should be:
public class YourClass{
private int id;
private String image;
//+ constructor, getters, setters,...
}
On server you can receive JSON from client side by InputStream is:
Reader reader = new InputStreamReader(is, "UTF-8");
Gson gson = new Gson();
List<YourClass> items = gson.fromJson(reader, new TypeToken<List<YourClass>>();
and then:
for (YourClass item: items){
//acces to item properties like item.id, item.image
}
iam trying to convert this json string back to an array but i can't seem to do it
["\"abba\"","\"repaper\"","\"minim\"","\"radar\"","\"murdrum\"","\"malayalam
\"","\"turrut\"","\"navan\""]
can anyone help, or point me in the right direction of some tutorials. Ive tried split(",") etc but im really not too sure how to extract the words themselves.
client code:
Gson gson;
String[] words = { "hello", "Abba", "repaper", "Minim", "radar",
"murdrum", "malayalam", "cheese", "turrut","Navan" };
gson = new Gson();
String json = gson.toJson(words);
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client
.resource("http://localhost:8090/RestSampleApp/rest/webservice/returnarray");
ClientResponse response = service.type(MediaType.APPLICATION_JSON)
.post(ClientResponse.class, json);
String output = response.getEntity(String.class);
//String target2 = gson.fromJson(json, String.class);
System.out.println(output);
webservice code:
#POST
#Path("returnarray")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String returnstuff(String list) {
list2 = list.substring(1, list.length() - 1); //gets rid of "[]"
temp = new ArrayList<String>(Arrays.asList(list2.split(",")));
Algorithim algo = new Algorithim(temp); // instance of algorithim class takes in arrayList
algo.getpalindromesarray(); //creates plaindrome arraylist
newlist = algo.getnewlist();
String details = gson.toJson(newlist);
return details;
}
EDIT: My previous answer wasn't correct, see this new one...
You are not using Gson correctly... You are serializing the objects well, but you're not doing a correct deserialization... I suggest you to take a brief look to Gson documentation, it's few lines and you'll understand it better...
First you serialize your array correctly in your client, with:
String json = gson.toJson(words);
Then you send it using Jersey API, I think that it's correct (although I'm not an expert in Jersey...)
Then your problem is that you are not deserializing the JSON correctly in your web service. You should parse the JSON string passed as a parameter, and you can do it with Gson as well, like this:
Gson gson = new Gson();
Type listOfStringsType = new TypeToken<List<String>>() {}.getType();
List<String> parsedList = gson.fromJson(list, listOfStringsType);
Now you can do whatever you want with your list of words working with a proper Java List.
Once you finish your work, you serialize again the List to return it, with:
String details = gson.toJson(parsedList);
Now you have to repeat the deserializing operation in your client to parse the response and get again a List<String>...
Note: You should never try to do things like serialize/deserialize JSON (or XML...) manually. A manual solution may work fine in a particular situation, but it can't be easily adapted to changes, thus, if your JSON responses change, even only slightly, you'll have to change a lot of code... Always use libraries for this kind of things!
You'd better use json library, e.g. Jackson. If code yourself, you can do like below:
// 1st: remove [ and ]
s=s.substring(1, s.length()-1);
// 2nd: remove "
s=s.replaceAll("\"\"", "");
// 3rd: split
String[] parts = s.split(",");
You can try to use String.format to specify the format you waant to pass as part of your request.
For Ex :
WebResource webResource = client.resource("http://localhost:8090/RestSampleApp/rest/webservice/returnarray");
String input = String.format("{\manual format "}",parameter);
ClientResponse response = webResource.type("application/json").post(ClientResponse.class, input);
This is how I have acheived my goal