I'm not too familiar with how to output files back to the client with Java. I am trying to create a CSV file to be sent back to the client and opened in Excel.
I found this tool for the server side creation. I'm not sure exactly how to use it to return the actual file though. Here is a sample of code I have used to return a txt file that I think I can use parts of the response for, but I'm not fetching a file anymore since I'm creating this CSV so I'm not sure what I can use.
In the code below my biggest question is what do I have to return with the controller and how do I accomplish that? I'm not sure what I need to be returning between that and also from the CSV writer to the controller. Any help would be appreciated.
Here's my code so far:
Controller:
#RequestMapping(value = "/web/csvexport", method = RequestMethod.POST)
protected void processCSV(HttpServletRequest request, HttpServletResponse response, #RequestBody String jsonRequest)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try {
CSVWriter csvWriter = new CSVWriter();
JsonFlattener jsonFlattener = new JsonFlattener();
String fileName = "StandardQuery";
csvWriter.writeAsCSV(jsonFlattener.parseJson(jsonRequest), fileName);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
CVS Writer:
public class CSVWriter {
public void writeAsCSV(List<Map<String, String>> flatJson, String fileName) throws FileNotFoundException {
Set<String> headers = collectHeaders(flatJson);
String output = StringUtils.join(headers.toArray(), ",") + "\n";
for (Map<String, String> map : flatJson) {
output = output + getCommaSeperatedRow(headers, map) + "\n";
}
writeToFile(output, fileName);
}
private void writeToFile(String output, String fileName) throws FileNotFoundException {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(fileName));
writer.write(output);
} catch (IOException e) {
e.printStackTrace();
} finally {
close(writer);
}
}
private void close(BufferedWriter writer) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String getCommaSeperatedRow(Set<String> headers, Map<String, String> map) {
List<String> items = new ArrayList<String>();
for (String header : headers) {
String value = map.get(header) == null ? "" : map.get(header).replace(",", "");
items.add(value);
}
return StringUtils.join(items.toArray(), ",");
}
private Set<String> collectHeaders(List<Map<String, String>> flatJson) {
Set<String> headers = new TreeSet<String>();
for (Map<String, String> map : flatJson) {
headers.addAll(map.keySet());
}
return headers;
}
}
Json Flattener:
public class JsonFlattener {
public Map<String, String> parse(JSONObject jsonObject) {
Map<String, String> flatJson = new HashMap<String, String>();
flatten(jsonObject, flatJson, "");
return flatJson;
}
public List<Map<String, String>> parse(JSONArray jsonArray) {
List<Map<String, String>> flatJson = new ArrayList<Map<String, String>>();
int length = jsonArray.length();
for (int i = 0; i < length; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Map<String, String> stringMap = parse(jsonObject);
flatJson.add(stringMap);
}
return flatJson;
}
public List<Map<String, String>> parseJson(String json) throws Exception {
List<Map<String, String>> flatJson = null;
try {
JSONObject jsonObject = new JSONObject(json);
flatJson = new ArrayList<Map<String, String>>();
flatJson.add(parse(jsonObject));
} catch (JSONException je) {
flatJson = handleAsArray(json);
}
return flatJson;
}
private List<Map<String, String>> handleAsArray(String json) throws Exception {
List<Map<String, String>> flatJson = null;
try {
JSONArray jsonArray = new JSONArray(json);
flatJson = parse(jsonArray);
} catch (Exception e) {
throw new Exception("Json might be malformed");
}
return flatJson;
}
private void flatten(JSONArray obj, Map<String, String> flatJson, String prefix) {
int length = obj.length();
for (int i = 0; i < length; i++) {
if (obj.get(i).getClass() == JSONArray.class) {
JSONArray jsonArray = (JSONArray) obj.get(i);
if (jsonArray.length() < 1) continue;
flatten(jsonArray, flatJson, prefix + i);
} else if (obj.get(i).getClass() == JSONObject.class) {
JSONObject jsonObject = (JSONObject) obj.get(i);
flatten(jsonObject, flatJson, prefix + (i + 1));
} else {
String value = obj.getString(i);
if (value != null)
flatJson.put(prefix + (i + 1), value);
}
}
}
private void flatten(JSONObject obj, Map<String, String> flatJson, String prefix) {
Iterator iterator = obj.keys();
while (iterator.hasNext()) {
String key = iterator.next().toString();
if (obj.get(key).getClass() == JSONObject.class) {
JSONObject jsonObject = (JSONObject) obj.get(key);
flatten(jsonObject, flatJson, prefix);
} else if (obj.get(key).getClass() == JSONArray.class) {
JSONArray jsonArray = (JSONArray) obj.get(key);
if (jsonArray.length() < 1) continue;
flatten(jsonArray, flatJson, key);
} else {
String value = obj.getString(key);
if (value != null && !value.equals("null"))
flatJson.put(prefix + key, value);
}
}
}
}
Here's the service that I'm calling the controller from. I used this to return a .txt file before so I'm not sure how usable it is, but I think if I stream the file back it will handle it...:
getFile: function(jsonObj, fileName) {
var _defer = $q.defer();
$http.post("/web/csvexport/", jsonObj).success(function(data, status, headers) {
var octetStreamMime = "application/octet-stream";
// Get the headers
headers = headers();
// Get the filename from the x-filename header or default to "download.bin"
//var filename = headers["x-filename"] || "logfile.log";
var filename = fileName;
// Determine the content type from the header or default to "application/octet-stream"
var contentType = headers["content-type"] || octetStreamMime;
if(navigator.msSaveBlob)
{
// Save blob is supported, so get the blob as it's contentType and call save.
var blob = new Blob([data], { type: contentType });
navigator.msSaveBlob(blob, filename);
console.log("SaveBlob Success");
}
else
{
// Get the blob url creator
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if(urlCreator)
{
// Try to use a download link
var link = document.createElement("a");
if("download" in link)
{
// Prepare a blob URL
var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute("href", url);
// Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
link.setAttribute("download", filename);
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
console.log("Download link Success");
} else {
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
window.location = url;
console.log("window.location Success");
}
} else {
console.log("Not supported");
}
}
Firstly, why don't use CSV mime type instead of html ?
replace
response.setContentType("text/html;charset=UTF-8");
by
response.setContentType("text/csv");
And do you know that Jackson, Java JSON API handle CSV ? see
https://github.com/FasterXML/jackson-dataformat-csv
Finaly, in the controler you need to use the printWriter from the response to write the CSV.
Dont forget, to prefer Stream or BufferedString to handle large file and have better performances.
Related
i try to migration a servlet project to webflux,but a MultipartFormData parse is different from them.
send request
#Test
public void testMutiplepart1() {
String url = "http://localhost:8081/multipartPart?category_id=115348&app_id=1000912×tamp=1673339039&sig=041b5b6e4e6eae430208f9fbc45dc3a8";
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(5);
map.add("category_id", "115348");
map.add("app_id", 1000912);
map.add("app_food_code", "1253");
map.add("timestamp", 1673339039);
map.add("sig", "041b5b6e4e6eae430208f9fbc45dc3a8");
String result = restTemplate.postForObject(url, map, String.class);
System.out.println(result);
}
parse multipValue
app_id and timestamp is not formField
private Map<String, String> getFormData(String path,
MultiValueMap<String, Part> partMultiValueMap) {
if (partMultiValueMap != null) {
Map<String, String> formData = new HashMap<>();
Map<String, Part> multiPartMap = partMultiValueMap.toSingleValueMap();
for (Map.Entry<String, Part> partEntry : multiPartMap.entrySet()) {
Part part = partEntry.getValue();
if (part instanceof FormFieldPart) {
formData.put(partEntry.getKey(), ((FormFieldPart) part).value());
} else {
log.warn("not support file part , uri:{} key:{} name:{}", path, partEntry.getKey(), part.name());
}
}
return formData;
}
return null;
}
webFlux judge a formField code
private static boolean isFormField(HttpHeaders headers) {
MediaType contentType = headers.getContentType();
//MediType is Text/Plain subContent
return (contentType == null || MediaType.TEXT_PLAIN.equalsTypeAndSubtype(contentType))
&& headers.getContentDisposition().getFilename() == null;
}
servlet judge formFiled code
String fieldName = getFieldName(headers);
if (fieldName != null) {
String subContentType = headers.getHeader(CONTENT_TYPE);
if (subContentType != null
&& subContentType.toLowerCase(Locale.ENGLISH)
.startsWith(MULTIPART_MIXED)) {
currentFieldName = fieldName;
// Multiple files associated with this field name
byte[] subBoundary = getBoundary(subContentType);
multi.setBoundary(subBoundary);
skipPreamble = true;
continue;
}
String fileName = getFileName(headers);
currentItem = new FileItemStreamImpl(fileName,
fieldName, headers.getHeader(CONTENT_TYPE),
//if fileName is null , the field is formField
fileName == null, getContentLength(headers));
currentItem.setHeaders(headers);
notifier.noteItem();
itemValid = true;
return true;
}
how can i parse the value ?
I want to form an Object of NamedList as this :
response={numFound=57279026,start=0,docs=[SolrDocument{timestamp_update=Thu Jan 01 01:00:00 CET 1970}]}}
When I do that I am getting an exception thrown when my code tries to access the result: SolrDocumentList results = response.getResults();
**java.lang.ClassCastException: org.apache.solr.common.util.SimpleOrderedMap cannot be cast to org.apache.solr.common.SolrDocumentList**
How should I create the NamedList, so that it doesn't throw an exception
Here is my way of doing it:
NamedList<Object> nl = new SimpleOrderedMap<>();
private static Map<String, Object> solrDocumentMap= new HashMap<>();
solrDocumentMap.put("timestamp_update", TIMESTAMP_UPDATE);
solrDocument= new SolrDocument(solrDocumentMap);
solrDocumentList.add(solrDocument);
nl.add("numFound", "57279026");
nl.add("start", "0");
nl.add("docs", solrDocumentList);
NamedList<Object> nl1 = new NamedList<>(Collections.singletonMap("response", nl));
response.setResponse(nl1);
Here is the in built class of QueryResponse which is casting the response to SolarDocument
public void setResponse(NamedList<Object> res) {
super.setResponse(res);
for(int i = 0; i < res.size(); ++i) {
String n = res.getName(i);
if ("responseHeader".equals(n)) {
this._header = (NamedList)res.getVal(i);
} else if ("response".equals(n)) {
this._results = (SolrDocumentList)res.getVal(i);
} else if ("sort_values".equals(n)) {
this._sortvalues = (NamedList)res.getVal(i);
} else if ("facet_counts".equals(n)) {
this._facetInfo = (NamedList)res.getVal(i);
} else if ("debug".equals(n)) {
this._debugInfo = (NamedList)res.getVal(i);
this.extractDebugInfo(this._debugInfo);
} else if ("grouped".equals(n)) {
this._groupedInfo = (NamedList)res.getVal(i);
this.extractGroupedInfo(this._groupedInfo);
} else if ("expanded".equals(n)) {
NamedList map = (NamedList)res.getVal(i);
this._expandedResults = map.asMap(1);
} else if ("highlighting".equals(n)) {
this._highlightingInfo = (NamedList)res.getVal(i);
this.extractHighlightingInfo(this._highlightingInfo);
} else if ("spellcheck".equals(n)) {
this._spellInfo = (NamedList)res.getVal(i);
this.extractSpellCheckInfo(this._spellInfo);
} else if ("clusters".equals(n)) {
this._clusterInfo = (ArrayList)res.getVal(i);
this.extractClusteringInfo(this._clusterInfo);
} else if ("suggest".equals(n)) {
this._suggestInfo = (Map)res.getVal(i);
this.extractSuggesterInfo(this._suggestInfo);
} else if ("stats".equals(n)) {
this._statsInfo = (NamedList)res.getVal(i);
this.extractStatsInfo(this._statsInfo);
} else if ("terms".equals(n)) {
this._termsInfo = (NamedList)res.getVal(i);
this.extractTermsInfo(this._termsInfo);
} else if ("moreLikeThis".equals(n)) {
this._moreLikeThisInfo = (NamedList)res.getVal(i);
} else if ("nextCursorMark".equals(n)) {
this._cursorMarkNext = (String)res.getVal(i);
}
}
if (this._facetInfo != null) {
this.extractFacetInfo(this._facetInfo);
}
}
I have finally found a solution, I hope this helps everyone. I got the response from Solr in XML format and read the file and parsed it with the XMLResponseParser. Somehow JsonParser is not working for Solar and if you use java deserialization, there is an existing bug in Solr for incompatibility.
This works well with the internal typecasting of query Response class as well.
protected QueryResponse getResponse(String fileName) throws IOException {
Path path = Paths.get(resDir + "/" + fileName);
InputStream body= new FileInputStream(path.toFile());
NamedList<Object> result= processResponse(body, null);
QueryResponse response = new QueryResponse();
response.setResponse(result);
return response;
}
private NamedList<Object> processResponse(InputStream body, Object o) {
XMLResponseParser parser= new XMLResponseParser();
NamedList<Object> result= parser.processResponse(body, "UTF-8");
return result;
}
I am able to return an HashMap as a JSON from my REST API built on Spring Boot. Here my Method:
#ResponseBody
#Transactional
#GetMapping("create_coinmarketcap_snapshot")
public ResponseEntity<HashMap> create_coinmarketcap_snapshot() {
String jsonString = callURL("https://api.coinmarketcap.com/v2/ticker/?limit=5");
JSONArray coinmarketcapsnapshotsArray = new JSONArray();
JSONObject coinmarketcapsnapshotsJSONObject = new JSONObject();
HashMap<Integer, CoinmarketcapSnapshot> coinmarketcapsnapshotsHashMap = new HashMap<>();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject jsonObjectData = jsonObject.getJSONObject("data");
Iterator<?> keys = jsonObjectData.keys();
int count = 0;
while (keys.hasNext()) {
count++;
String key = (String) keys.next();
if (jsonObjectData.get(key) instanceof JSONObject) {
JSONObject jsonObjectDataCrypto = jsonObjectData.getJSONObject(key);
JSONObject jsonObjectDataCryptoQuotes = jsonObjectDataCrypto.getJSONObject("quotes").getJSONObject("USD");
CoinmarketcapSnapshot coinmarketcapsnapshotObject = new CoinmarketcapSnapshot();
String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
coinmarketcapsnapshotObject.setTitle(jsonObjectDataCrypto.get("name") + " - " + dateFormatted);
coinmarketcapsnapshotObject.setCryptocurrencyId((int) jsonObjectDataCrypto.get("id"));
if(jsonObjectDataCrypto.get("rank")!=null){
coinmarketcapsnapshotObject.setRank((int) jsonObjectDataCrypto.get("rank"));
}
if(jsonObjectDataCrypto.get("circulating_supply")!=null){
coinmarketcapsnapshotObject.setCirculatingSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
}
if(jsonObjectDataCrypto.get("total_supply")!=null){
coinmarketcapsnapshotObject.setTotalSupply((Double) jsonObjectDataCrypto.get("total_supply"));
}
if(!jsonObjectDataCrypto.isNull("circulating_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
}
if(!jsonObjectDataCrypto.isNull("total_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("total_supply"));
}
if(!jsonObjectDataCrypto.isNull("max_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("max_supply"));
}
if(!jsonObjectDataCryptoQuotes.isNull("price")) {
coinmarketcapsnapshotObject.setPrice((Double) jsonObjectDataCryptoQuotes.get("price"));
}
if(!jsonObjectDataCryptoQuotes.isNull("volume_24h")) {
coinmarketcapsnapshotObject.setVolume24h((Double) jsonObjectDataCryptoQuotes.get("volume_24h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("market_cap")) {
coinmarketcapsnapshotObject.setMarketCap((Double) jsonObjectDataCryptoQuotes.get("market_cap"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_1h")) {
coinmarketcapsnapshotObject.setPercentChange1h((Double) jsonObjectDataCryptoQuotes.get("percent_change_1h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_24h")) {
coinmarketcapsnapshotObject.setPercentChange24h((Double) jsonObjectDataCryptoQuotes.get("percent_change_24h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_7d")) {
coinmarketcapsnapshotObject.setPercentChange7d((Double) jsonObjectDataCryptoQuotes.get("percent_change_7d"));
}
entityManager.persist(coinmarketcapsnapshotObject);
coinmarketcapsnapshotsArray.put(coinmarketcapsnapshotObject);
coinmarketcapsnapshotsJSONObject.put(String.valueOf(count),coinmarketcapsnapshotObject);
coinmarketcapsnapshotsHashMap.put(count, coinmarketcapsnapshotObject);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("\n\ncoinmarketcapsnapshotsArray:\n"+coinmarketcapsnapshotsArray);
System.out.println("\n\ncoinmarketcapsnapshotsJSONObject:\n"+coinmarketcapsnapshotsJSONObject);
System.out.println("\n\ncoinmarketcapsnapshotsHashMap:\n"+coinmarketcapsnapshotsHashMap);
return new ResponseEntity<>(coinmarketcapsnapshotsHashMap, HttpStatus.OK);
}
Here is what is printed in the terminal:
coinmarketcapsnapshotsArray:
["com.krown.entity.CoinmarketcapSnapshot#4d60f69f","com.krown.entity.CoinmarketcapSnapshot#4739c2f2","com.krown.entity.CoinmarketcapSnapshot#7d5bd573","com.krown.entity.CoinmarketcapSnapshot#43b5eb6d","com.krown.entity.CoinmarketcapSnapshot#26e1a633"]
coinmarketcapsnapshotsJSONObject:
{"1":"com.krown.entity.CoinmarketcapSnapshot#4d60f69f","2":"com.krown.entity.CoinmarketcapSnapshot#4739c2f2","3":"com.krown.entity.CoinmarketcapSnapshot#7d5bd573","4":"com.krown.entity.CoinmarketcapSnapshot#43b5eb6d","5":"com.krown.entity.CoinmarketcapSnapshot#26e1a633"}
coinmarketcapsnapshotsHashMap:
{1=com.krown.entity.CoinmarketcapSnapshot#4d60f69f, 2=com.krown.entity.CoinmarketcapSnapshot#4739c2f2, 3=com.krown.entity.CoinmarketcapSnapshot#7d5bd573, 4=com.krown.entity.CoinmarketcapSnapshot#43b5eb6d, 5=com.krown.entity.CoinmarketcapSnapshot#26e1a633}
I want to return my JSONObject "coinmarketcapsnapshotsJSONObject" instead "coinmarketcapsnapshotsHashMap", but when I do it, I keep getting stuck with this error:
No converter found for return value of type: class org.json.JSONObject
As suggested in some posts found on web, I added Jackson as new dependency in pom.xml file:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
Unfortunately this didn't change anything.
Do you have any suggestion to improve the process of building a JSON for a REST API on Spring Boot?
When I return the HashMap, the output looks like that:
#GetMapping(produces={MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> create_coinmarketcap_snapshot() throws IOException {
UriComponentsBuilder builder =
UriComponentsBuilder.fromUriString("https://api.coinmarketcap.com/v2/ticker")
.queryParam("limit", "5");
ResponseEntity<String> response =
restTemplate.getForEntity(builder.toUriString(), String.class);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
JsonNode data = root.path("data");
data.forEach(jsonObject -> {
jsonObject.get("rank"); //extracting values from each json object
jsonObject.get("circulating_supply");
jsonObject.get("total_supply");
jsonObject.get("max_supply");
jsonObject.get("price");
jsonObject.get("volume_24h");
jsonObject.get("market_cap");
jsonObject.get("percent_change_1h");
jsonObject.get("percent_change_24h");
//... and so on
});
return ResponseEntity.ok(data);
}
Now you're returning a json object that contains the value of "data" key #118218
HttpStatus.OK is the default return value for Http endpoints using Spring and therefore specifying it is unnecessary, thereby rendering the entire ResponseEntity unnecessary:
#ResponseBody
#Transactional
#GetMapping("create_coinmarketcap_snapshot")
public HashMap create_coinmarketcap_snapshot() {
String jsonString = callURL("https://api.coinmarketcap.com/v2/ticker/?limit=5");
JSONArray coinmarketcapsnapshotsArray = new JSONArray();
JSONObject coinmarketcapsnapshotsJSONObject = new JSONObject();
HashMap<Integer, CoinmarketcapSnapshot> coinmarketcapsnapshotsHashMap = new HashMap<>();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject jsonObjectData = jsonObject.getJSONObject("data");
Iterator<?> keys = jsonObjectData.keys();
int count = 0;
while (keys.hasNext()) {
count++;
String key = (String) keys.next();
if (jsonObjectData.get(key) instanceof JSONObject) {
JSONObject jsonObjectDataCrypto = jsonObjectData.getJSONObject(key);
JSONObject jsonObjectDataCryptoQuotes = jsonObjectDataCrypto.getJSONObject("quotes").getJSONObject("USD");
CoinmarketcapSnapshot coinmarketcapsnapshotObject = new CoinmarketcapSnapshot();
String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
coinmarketcapsnapshotObject.setTitle(jsonObjectDataCrypto.get("name") + " - " + dateFormatted);
coinmarketcapsnapshotObject.setCryptocurrencyId((int) jsonObjectDataCrypto.get("id"));
if(jsonObjectDataCrypto.get("rank")!=null){
coinmarketcapsnapshotObject.setRank((int) jsonObjectDataCrypto.get("rank"));
}
if(jsonObjectDataCrypto.get("circulating_supply")!=null){
coinmarketcapsnapshotObject.setCirculatingSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
}
if(jsonObjectDataCrypto.get("total_supply")!=null){
coinmarketcapsnapshotObject.setTotalSupply((Double) jsonObjectDataCrypto.get("total_supply"));
}
if(!jsonObjectDataCrypto.isNull("circulating_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("circulating_supply"));
}
if(!jsonObjectDataCrypto.isNull("total_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("total_supply"));
}
if(!jsonObjectDataCrypto.isNull("max_supply")) {
coinmarketcapsnapshotObject.setMaxSupply((Double) jsonObjectDataCrypto.get("max_supply"));
}
if(!jsonObjectDataCryptoQuotes.isNull("price")) {
coinmarketcapsnapshotObject.setPrice((Double) jsonObjectDataCryptoQuotes.get("price"));
}
if(!jsonObjectDataCryptoQuotes.isNull("volume_24h")) {
coinmarketcapsnapshotObject.setVolume24h((Double) jsonObjectDataCryptoQuotes.get("volume_24h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("market_cap")) {
coinmarketcapsnapshotObject.setMarketCap((Double) jsonObjectDataCryptoQuotes.get("market_cap"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_1h")) {
coinmarketcapsnapshotObject.setPercentChange1h((Double) jsonObjectDataCryptoQuotes.get("percent_change_1h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_24h")) {
coinmarketcapsnapshotObject.setPercentChange24h((Double) jsonObjectDataCryptoQuotes.get("percent_change_24h"));
}
if(!jsonObjectDataCryptoQuotes.isNull("percent_change_7d")) {
coinmarketcapsnapshotObject.setPercentChange7d((Double) jsonObjectDataCryptoQuotes.get("percent_change_7d"));
}
entityManager.persist(coinmarketcapsnapshotObject);
coinmarketcapsnapshotsArray.put(coinmarketcapsnapshotObject);
coinmarketcapsnapshotsJSONObject.put(String.valueOf(count),coinmarketcapsnapshotObject);
coinmarketcapsnapshotsHashMap.put(count, coinmarketcapsnapshotObject);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("\n\ncoinmarketcapsnapshotsArray:\n"+coinmarketcapsnapshotsArray);
System.out.println("\n\ncoinmarketcapsnapshotsJSONObject:\n"+coinmarketcapsnapshotsJSONObject);
System.out.println("\n\ncoinmarketcapsnapshotsHashMap:\n"+coinmarketcapsnapshotsHashMap);
return coinmarketcapsnapshotsHashMap;
}
I'm trying to use the Safe Browsing API from google to check if a web link is black listed, just need to send a request within a JSON object to:
POST https://safebrowsing.googleapis.com/v4/threatMatches:find?key=API_KEY HTTP/1.1
Content-Type: application/json
And the JSON object should be like:
{
"client": {
"clientId": "mycompanyname",
"clientVersion": "1.1"
},
"threatInfo": {
"threatTypes": ["MALWARE", "SOCIAL_ENGINEERING"],
"platformTypes": ["WINDOWS"],
"threatEntryTypes": ["URL"],
"threatEntries": [
{"url": "http://www.urltocheck1.org/"},
{"url": "http://www.urltocheck2.org/"},
{"url": "http://www.urltocheck3.com/"}
]
}
}
But already I don't know if I am formatting my JSON object properly, or my code is correct, see below:
public class SB {
private ArrayList<String> url; //URL's a analizar
private String key; //API key
private RequestQueue queue;
private Context context;
private ArrayList<SBthreat> AnalyzedUrl; //analysis final
private boolean Interrupted = false;
private boolean CallFail = false;
public SB(Context context, ArrayList<String> url, String key){
this.url = url;
this.key = key;
this.context = context;
queue = Volley.newRequestQueue(context);
AnalyzedUrl = new ArrayList<>();
}
public void Request(){
final StringBuilder api = new StringBuilder("https://safebrowsing.googleapis.com/v4/threatMatches:find?key=");
JSONObject requestBody = new JSONObject();
//JSON body
try {
JSONObject client = new JSONObject();
client.put("clientId", "NetworkSentinel");
client.put("clientVersion", "1.2");
JSONObject threatEntries = new JSONObject();
for(int i = 0; i < this.url.size(); i++){
threatEntries.put("url", this.url.get(i)); //-----> the url can be too many
}
JSONObject threatInfo = new JSONObject();
threatInfo.put("threatTypes", "[\"MALWARE\", \"SOCIAL_ENGINEERING\"]");
threatInfo.put("platformTypes", "[\"WINDOWS\"]");
threatInfo.put("threatEntryTypes", "[\"URL\"]");
threatInfo.put("threatEntries", threatEntries);
JSONObject jsonBody = new JSONObject();
jsonBody.put("client", client);
jsonBody.put("threatInfo", threatInfo);
requestBody.put("", jsonBody);
}catch (JSONException e) {
e.printStackTrace();
}
api.append(key).append(" HTTP/1.1");
Log.i("SB", api.toString().replace(key, "XXXXXXXXXXXXX"));
RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, api.toString(), requestBody, future, future){
#Override
public HashMap<String, String> getHeaders() {
HashMap<String, String> params = new HashMap<>();
params.put("Content-Type", "application/json");
return params;
}
};
queue.add(request);
try {
JSONObject response = future.get();
if(response.length() != 0) {
Log.i("SB", "-----------------------------------------------------------------------");
Log.i("response", response.toString());
Interrupted = false;
CallFail = false;
}
} catch (InterruptedException e) {
e.printStackTrace();
Interrupted = true;
} catch (ExecutionException e) {
e.printStackTrace();
CallFail = true;
}
}
public ArrayList<SBthreat> GetAnalysis(){
return AnalyzedUrl;
}
public boolean isInterrupted(){
return Interrupted;
}
public boolean isCallFail(){
return CallFail;
}
}
Is the code threatInfo.put("threatTypes", "[\"MALWARE\", \"SOCIAL_ENGINEERING\"]"); well written? Or is there is a better way to put data in square brackets?
When I run my code always get the error com.android.volley.ClientError and connections errors, what I'm doing wrong?
You should use JSONArray and don't use [ ] to place manually. Please refer below:
JSONObject client = new JSONObject();
client.put("clientId", "mycompanyname");
client.put("clientVersion", "1.1");
JSONObject threatInfo = new JSONObject();
JSONArray threatTypes = new JSONArray();
threatTypes.put("MALWARE");
threatTypes.put("SOCIAL_ENGINEERING");
JSONArray platformTypes = new JSONArray();
threatTypes.put("WINDOWS");
JSONArray threatEntryTypes = new JSONArray();
threatTypes.put("URL");
JSONArray threatEntries = new JSONArray();
for(int i = 0; i < this.url.size(); i++){
JSONObject threatEntry = new JSONObject();
threatEntry.put("url", this.url.get(i)); //-----> the url can be too many
threatEntries.put(threatEntry);
}
threatInfo.put("threatTypes", threatTypes);
threatInfo.put("platformTypes", platformTypes);
threatInfo.put("threatEntryTypes", threatEntryTypes);
threatInfo.put("threatEntries", threatEntries);
How would I get all the "name" values and turn them into a String?
So for example if I'd do the following:
System.out.println(value[1]);
It would print out name1.
Here is what I have so far:
JSON:
[
{
"name":"name1"
},
{
"name":"name2",
"changedToAt":1470659096000
},
{
"name":"name3",
"changedToAt":1473435817000
}
]
Java code:
try {
String UUID = p.getUniqueId().toString();
String slimUUID = UUID.replace("-", "");
InputStream in = new URL("https://api.mojang.com/user/profiles/" + slimUUID + "/names").openStream();
String json = IOUtils.toString(in);
IOUtils.closeQuietly(in);
try {
JSONParser parser = new JSONParser();
JSONObject jsonparse = (JSONObject) parser.parse(json);
//get "name" values and turn into String
} catch (ParseException e) {
System.out.println(e.getMessage());
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
You need to iterate over array and accumulate all name values into array of Strings.
So below is working source code:
JsonArray jsonObject = new JsonParser()
.parse(json)
.getAsJsonArray();
List<String> names = new ArrayList<>();
for (JsonElement jsonElement : jsonObject) {
names.add(jsonElement.getAsJsonObject().get("name").getAsString());
}
//now you can use as you wish, by index
System.out.println(names.get(1));//returns "name2"
Using the URL from your comment and Java 8 Stream API I've built this main method:
public static void main(final String[] args) throws ParseException, MalformedURLException, IOException {
final String url = "https://api.mojang.com/user/profiles/c8570e47605948d3a3cbe3ec3a681cc0/names";
final InputStream in = new URL(url).openStream();
final String json = IOUtils.toString(in);
IOUtils.closeQuietly(in);
final JSONParser parser = new JSONParser();
final JSONArray jsonparse = (JSONArray) parser.parse(json);
System.out.println(jsonparse);
System.out.println();
final List<String> names = (ArrayList<String>) jsonparse.stream().map((obj) -> {
final JSONObject object = (JSONObject) obj;
return (String) object.getOrDefault("name", "");
}).peek(System.out::println).collect(Collectors.toList());
}
Try My library: abacus-common. All the above can be replaced with:
List<Map<String, Object>> resp = HttpClient.of("https://api.mojang.com/user/profiles/" + slimUUID + "/names").get(List.class);
List<String> names = resp.stream().map(m -> (String) (m.get("name"))).collect(Collectors.toList());
By the way, if slimUUID is equal to: UUID.randomUUID().toString().replaceAll("-", ""). It's be simplified:
List<Map<String, Object>> resp = HttpClient.of("https://api.mojang.com/user/profiles/" + N.guid()+ "/names").get(List.class);
List<String> names = resp.stream().map(m -> (String) (m.get("name"))).collect(Collectors.toList());