JSON: Create a web page with JSON data - java

Firstly, I am extremely new to JSON. I have been reading as much as I can on it. While I get the concept, implementing it is a different deal altogether for me.
So, I have an app which reads and displays data from JSON web pages. For instance, I can extract the time that is being shown in this website: http://date.jsontest.com/
Using the HTML from this website, I added the JSON Object to my HTML page in the following manner:
<html>
<body>
<pre>
{
"score": "30-20"
}
</pre>
</body>
</html>
However, the app now throws a JSON exception everytime I try to retreive the score.
My question is, 'Is adding a JSON Object to the pre tag in an HTML page the correct way of creating a JSON Object on a web page?'
If not, what is the correct way to do it?
EDIT: This is is the code I am using in java to retrieve the JSON data:
StringBuilder url = new StringBuilder(URL);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if(status==200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
//JSONArray timeline = new JSONArray(0);
JSONObject last = new JSONObject(data);
return last;
}
else{
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
return null;
}
The try statement:
try {
json = lastTweet();
return json.getString("time");
//return "Oh Well";
}
Thanks.

Your application should send the Content-type: application/json header and should only output the string representation of the data itself, so that your entire page is just:
{
"score": "30-20"
}
and nothing more. The example that you gave follows the same procedure if you check the response headers and view the source code of that page.
The reason your parser is failing is because the page starts with <, when the first non-whitespace character should be {.

Use something like this:
response.setContentType("application/json");
PrintWriter out = response.getWriter();
String json = "{\"data\": \"test\"}";
out.print(json);
out.flush();
on your dataserver

Related

How do I make a post request with dynamic values for some attributes stored in external JSON file?

I have a BDD automation framework setup with Selenium WebDriver and Cucumber with Java. I have configured Rest Assured and I am currently using one JSON payload which is stored in an external JSON file. I am directly reading this JSON file into byte array and then converting the same to String and sending the payload to a post request.
Till now, everything was static and hence, this was working without any issue. However, now the requirement is to send a couple of attributes with dynamic values everytime I make a post call. I know how to send a complete dynamic payload using POJOs but I am looking for a different solution where I can read the payload from the same JSON file and can send dynamic values for few required attributes. Please let me know if this is possible.
Attaching the code for reference.
File which reads the JSON file and sends the payload to post request
public class AddOrderAPIActions {
ConfigReader configReader = new ConfigReader();
Properties prop;
public AddOrderAPIActions() {
prop = configReader.init_prop();
}
//Setting up the API URI
public void setURI() {
String URI = prop.getProperty("apiURI");
RestAssured.baseURI = URI;
}
//Sending the request payload via POST method
public String sendRequestPayload() throws IOException {
//read data from local JSON file then store in byte array
byte[] b = Files.readAllBytes(Paths.get("./src/test/resources/data/addOrder.json"));
//convert byte array to string
String bdy = new String(b);
//input details with header and body
Response response = given().header("Content-type", "application/json").queryParam("api_key", prop.getProperty("apiKey")).body(bdy)
//adding post method
.when().post().then().log().all().extract().response();
JsonPath jp = response.jsonPath();
String shipmentNumber = jp.get("data.shipmentDetails[0].shipmentNumber");
System.out.println("Shipment Number is "+ shipmentNumber);
return shipmentNumber;
}
}
The JSON file with payload
[
{
"originDetails": {
"originCode": "Dynamic_Value",
"originStartTime": "",
"originEndTime": "",
"senderName": "Origin Name",
"senderContactNumber": "9999999999",
"senderAddress": "Bali, Indonesia",
"senderPincode": "201001",
"senderCity": "Delhi",
"senderCountry": "India"
},
]
Here, I want to send a dynamic value for "originCode" attribute and rest of the attributes should be sent as read from the JSON file.
Thanks in advance.

Java - Access JSON Element (llegalFormatConversionException: d !=java.lang.String)

I am trying to learn JAVA and build a plugin for Minecraft; I have been successfully able to get the JSON data from my api endpoint however, the issue I am facing right now is an llegalFormatConversionException: d !=java.lang.String which means that the format I am trying to make into string isn't equal to the type of string that it's looking for.
I am trying to access a JSON element from my endpoint called condition
{
"todaysdate": "2021-02-12",
"temperature": 25,
"description": [
"Overcast"
],
"condition": 122,
}
Coming from C#; I know there's a website called json2sharp where you can create a root class for the JSON. I'm not sure how it would be applied in Java but currently, my code looks like this.
private String fetchWeather() throws IOException, InvalidConfigurationException {
// Download
final URL url = new URL(API);
final URLConnection request = url.openConnection();
// Set HEADER
request.setRequestProperty("x-api-key", plugin.apiKey);
request.setConnectTimeout(5000);
request.setReadTimeout(5000);
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject();
//JsonElement code = rootobj.get("condition");
String condition_code = rootobj.get("condition").toString();
plugin.getLogger().fine(String.format(
"[%s] Weather is %d",
world.getName(), condition_code
));
return condition_code;
}
If I call
private JsonObject fetchWeather() throws IOException, InvalidConfigurationException {
// Download
final URL url = new URL(API);
final URLConnection request = url.openConnection();
// Set HEADER
request.setRequestProperty("x-api-key", plugin.apiKey);
request.setConnectTimeout(5000);
request.setReadTimeout(5000);
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject();
return rootobj;
}
state = fetchWeather();
plugin.getLogger().warning(state.toString());
I do get the actual JSON with all of the elements so I know the URL and accessing it is completely working, but I get an llegalexception for format if I try to call and print with logger the condition code.
So, if I change the return type in fetchWeather() to be the root json object and then try to print it with the state variable above it works; but if I try to return the condition json element and print it it gives me an iilegal exception.
Now before I posted this question I did read some other questions people had but I couldn't get a working solution from their suggested answers. So, I am hoping someone can point me out on what I'm doing wrong because I know I'm messing up somewhere with the variable format.
Thanks.
Line 37: state = fetchWeather();
Line 103:
plugin.getLogger().fine(String.format(
"[%s] Weather is %d",
world.getName(), bId
));
condition_code variable is String. You should use the %s format specifier.

How to allow the user to download a byte[] or base64 to their chosen directory

I want to allow the user to download a pdf file created in iText.
The expected result is that the user can download the pdf to their selected directory. The actual result is the file will not download.
I am generating a pdf using iText and passing the result back to my ajax call to allow the user to download the file. I have the base64. I checked that it was valid by using https://base64.guru/converter/decode/pdf This showed the pdf correctly. However, I can not get the result to download in the ajax ".done".
I have tried using:
byte[] decoder = Base64.getDecoder().decode(b64);
Before passing it back; however, I get an error message on ".getDecoder()" of "The method getDecoder() is undefined for the type Base64".
The java code is:
resourceImage = MySQLConnection.recipePDF(accountID, crID, servings, servingSize);
String imageDataString = Base64Encode2.encode(resourceImage);
System.out.println("imageDataString: " + imageDataString);
if (resourceImage == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No recipe pdf.");
} else {
String json = new Gson().toJson(imageDataString);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
The javascript/ajax code on the is:
.done(function(responseJson1a){
dataType: "json";
alert(JSON.stringify(responseJson1a));
download(responseJson1a, "resourcefile.pdf", "application/pdf");
});
A very simple answer. I needed to add "data:application/pdf;base64," to the start of the string.
download("data:application/pdf;base64,"+responseJson1a, "resourcefile.pdf", "application/pdf");

how to read FAKE JSON response from ticker API of unocoin bitcoin exchange?

First of all i am sorry if i am wrong that the response is fake JSON ...
the api i am using is ticker api of unocoin
https://www.unocoin.com/trade?all
I have been working on a website which takes the rate from various indian bitcoin exchanges and plot the graphs for easy visualization.So far i have added 3 exchanges and got their rate from their TICKER API,the response i got is just plane text and no other surprises..
all these exchanges like
ZEBPAY: https://www.zebapi.com/api/v1/market/ticker/btc/inr
Koinex: https://koinex.in/api/ticker
made my life easier but
making a get request to unocoin api gives me a html page with only an iframe in body tag and i am not able to directly(or indirectly) use data in my code.
there is an alternate method to get access to many features but it requires me to register and feed my ACCESS TOKEN in every request which i don't prefer right now.
to make api calls i am using java and code is given belowe:
private static String sendGet(String host,String apiEndpoint) throws Exception {
URL obj = new URL(host+apiEndpoint);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
System.out.println(responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return(response.toString());
}
just a note: i got google recaptcha if i make a lot of request in small time frame
the result from above code is
<html><head><META NAME="robots" CONTENT="noindex,nofollow"><script src="/_Incapsula_Resource?SWJIYLWA=2977d8d74f63d7f8fedbea018b7a1d05"></script><script>(function() { var z="";var b="7472797B766172207868723B76617220743D6E6577204461746528292E67657454696D6528293B766172207374617475733D227374617274223B7661722074696D696E673D6E65772041727261792833293B77696E646F772E6F6E756E6C6F61643D66756E6374696F6E28297B74696D696E675B325D3D22723A222B286E6577204461746528292E67657454696D6528292D74293B646F63756D656E742E637265617465456C656D656E742822696D6722292E7372633D222F5F496E63617073756C615F5265736F757263653F4553324C555243543D363726743D373826643D222B656E636F6465555249436F6D706F6E656E74287374617475732B222028222B74696D696E672E6A6F696E28292B222922297D3B69662877696E646F772E584D4C4874747052657175657374297B7868723D6E657720584D4C48747470526571756573747D656C73657B7868723D6E657720416374697665584F626A65637428224D6963726F736F66742E584D4C4854545022297D7868722E6F6E726561647973746174656368616E67653D66756E6374696F6E28297B737769746368287868722E72656164795374617465297B6361736520303A7374617475733D6E6577204461746528292E67657454696D6528292D742B223A2072657175657374206E6F7420696E697469616C697A656420223B627265616B3B6361736520313A7374617475733D6E6577204461746528292E67657454696D6528292D742B223A2073657276657220636F6E6E656374696F6E2065737461626C6973686564223B627265616B3B6361736520323A7374617475733D6E6577204461746528292E67657454696D6528292D742B223A2072657175657374207265636569766564223B627265616B3B6361736520333A7374617475733D6E6577204461746528292E67657454696D6528292D742B223A2070726F63657373696E672072657175657374223B627265616B3B6361736520343A7374617475733D22636F6D706C657465223B74696D696E675B315D3D22633A222B286E6577204461746528292E67657454696D6528292D74293B6966287868722E7374617475733D3D323030297B706172656E742E6C6F636174696F6E2E72656C6F616428297D627265616B7D7D3B74696D696E675B305D3D22733A222B286E6577204461746528292E67657454696D6528292D74293B7868722E6F70656E2822474554222C222F5F496E63617073756C615F5265736F757263653F535748414E45444C3D313539373232303738303038363836383835372C31313637303136303238393537363439373530392C373430383533373634363033313237303235322C353332303936222C66616C7365293B7868722E73656E64286E756C6C297D63617463682863297B7374617475732B3D6E6577204461746528292E67657454696D6528292D742B2220696E6361705F6578633A20222B633B646F63756D656E742E637265617465456C656D656E742822696D6722292E7372633D222F5F496E63617073756C615F5265736F757263653F4553324C555243543D363726743D373826643D222B656E636F6465555249436F6D706F6E656E74287374617475732B222028222B74696D696E672E6A6F696E28292B222922297D3B";for (var i=0;i<b.length;i+=2){z=z+parseInt(b.substring(i, i+2), 16)+",";}z = z.substring(0,z.length-1); eval(eval('String.fromCharCode('+z+')'));})();</script></head><body><iframe style="display:none;visibility:hidden;" src="//content.incapsula.com/jsTest.html" id="gaIframe"></iframe></body></html>
i just want the response just like i get in my browser after visiting
https://www.unocoin.com/trade?all
The website is protected by an anti-scraping script called Incapsula that tries to run a small Javascript bit, but since you are using Java it won't be able to run it, unless you are using Selenium or like the V8 engine, but this is a bit not recommended because you are somehow breaking the rules of what they considered to be intrusive for them, but my recommendation:
Talk with the guys from unocoin.com and ask them to whitelist your IP if they are okay with you scraping their site.
Instead of using the API, you can do it by scraping the Unocoin Ticker API All Rates webpage. This would break if there is some change in the website, but till then it works.
It can be implemented via WebKit using WKWebView, WKNavigationDelegate protocol and then injecting some JavaScript.
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.isHidden = true
webView.navigationDelegate = self
let myURL = URL(string: "https://www.unocoin.com/trade?all")
let myRequest = URLRequest(url: myURL!)
webView.load(myRequest)
}
// For checking if website has loaded
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// Injecting JS to fetch HTML inside <body>
webView.evaluateJavaScript("document.body.innerHTML", completionHandler: {
(html: Any?, error: Error?) in
if error == nil && html != nil {
// Perform string manipulation and parse JSON to get data
} else {
// Error while fetching data
}
})
}
}

How to parse multi-part form data in wicket

When my page gets hit from a third party page, I get the below data in request payload:
Content-type: multipart/form-data, boundary----------14048
Content-Length = 590
----------14048
Content-disposition: form-data; name ="xyz"
{"abc":"lmn","def":"ghi"}
----------14048
I need to read the JSON string from this parameter in my Java class. How can I do that?
My current code looks like this:
IRequestParameters requestParameters = getRequest().getPostParameters();
if (requestParameters != null && requestParameters.getParameterNames().contains( "abc" )&&requestParameters.getParameterValue( "abc" ) != null){
  value = requestParameters.getParameterValue( "abc" ).toString();
}
Thanks in advance.
First, you need to parse multipart form data in Wicket:
MultipartServletWebRequest multiPartRequest =
webRequest.newMultipartWebRequest(getMaxSize(), "ignored");
// multiPartRequest.parseFileParts(); // this is needed after Wicket 6.19.0+
IRequestParameters params = multiPartRequest.getRequestParameters();
Then you need to parse the JSON fragment, one way to do that is by using org.json.
import org.json.*;
JSONObject jsondict = new JSONObject(params.getParameter("xyz");
Then you need to get the JSON parameter you are interested in:
string payload = jsondict.getString("abc");
The below code works fine for me.
HttpSevletRequest request = (HttpSevletRequest )getRequest.getContainerRequest();
try{
InputStreamReader inputReader = new InputStreamReader(request.getInputStream());
BufferedReader reader = new BufferedReader(inputReader );
for(String line;(line = reader.readLine())!=null;){
if(line.contains("abc")){
//perform task....
}
}
}catch(IOException e){
//logs
}

Categories