I really hate to do this, but I have two questions: can Jackson 2.7.3 parse the following url and can do I have to parse every part of the JSON?
Here is the code I am working with so far:
public class Song {
private String tracks;
private String album;
private String images;
public void setTracks(String tracks){
this.tracks=tracks;
}
public void setAlbum(String album){
this.album= album;
}
public void setImages (String images){
this.images= images;
}
}
And
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
ObjectMapper mapper = new ObjectMapper();
Document doc = Jsoup.connect("http://api.spotify.com/v1/search?q=track:" + finalSong + "%20artist:" + finalArtist+"%20" + "&type=track").ignoreContentType(true).get();
String title = String.valueOf(doc.body().text());
Song obj = mapper.readValue(String.valueOf(title), Song.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
return null;
}
All I need is the "preview_url" and one of the "images" url towards the top
the JSON is located at https://api.spotify.com/v1/search?q=track:Ready%20To%20Fall%20artist:rise%20against%20&type=track.
Do you necessary need to map your Json response into a class?
If not you can get your desired values as following e.g. for preview_url
You can use readTree to map the json result into a tree of nodes.
There after you can use findPath to search for the property you looking for.
In the case of image it contains an array. Thus if you want to select a specific item from that list you get use get to select the specific item you want.
example
JsonNode readTree = mapper.readTree(body);
for (JsonNode node : readTree.findPath("items")) {
System.out.println(node.findPath("images").get(2));
System.out.println(node.findPath("preview_url"));
}
Related
I'm having trouble converting a List object and it's returning the error below:
expected S in value {L: [{M: {txt_just={S: new client,}, num_funl={S: 123,}, num_propt={S: 2f1a8e6c-68bb-4c26-9326-3823d9f96c4c,}, ind_decs={S: S,}, dat_hor={S: 20220721183000,}},}],}
My Class translator:
public class ObjectTranslators<T> implements DynamoDBTypeConverter<String, T> {
private static final ObjectMapper mapper = new ObjectMapper();
#Override
public String convert(T t) {
try {
return mapper.writeValueAsString(t);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Unable to parse JSON");
}
}
#Override
public T unconvert(String s) {
try {
return mapper.readValue(s, new TypeReference<>() {});
} catch (IOException e) {
throw new IllegalArgumentException("Unable to read JSON");
}
}
}
You are trying to convert a List that has a single entry which is a Map of 5 key/value pairs. Your real issue is probably that there is no value supplied to ind_decs but, it's also possible that you aren't properly using the expected generic T type wherever ObjectTranslators is used as well.
expected S in value
{
L: [
{
M: {
txt_just={S: new client,},
num_funl={S: 123,},
num_propt={S: 2f1a8e6c-68bb-4c26-9326-3823d9f96c4c,},
ind_decs={S: S,},
dat_hor={S: 20220721183000,}
},
}
],
}
I keep getting this error, the path has been specified in yml and even in the console it is going to the relative path but not reading the file or finding it, how can I get past this ?
I have attached the picture and below is the code in my main method. Any input is deeply appreciated. Thanks!
#SpringBootApplication
#EnableConfigurationProperties(DataStaxAstraProperties.class)
public class BookAppApplication {
#Autowired AuthorRepostories authorRepostories;
#Value("${datadump.location.author}")
private String authorDumpsLocation;
#Value("${datadump.location.works}")
private String authorWorksLocation;
public static void main(String[] args) {
SpringApplication.run(BookAppApplication.class, args);
}
private void initAuthors() {
Path path = Paths.get(authorDumpsLocation);
System.out.println(path.toAbsolutePath());
try(Stream<String> lines = Files.lines(path)){
lines.forEach(line->{
String jsonStr = line.substring(line.indexOf("{"));
try {
JSONObject jsonObject = new JSONObject(jsonStr);
Author author = new Author();
author.setName(jsonObject.optString("name"));
author.setPersonalName(jsonObject.optString("personal_name"));
author.setId(jsonObject.optString("key").replace("/authors/",""));
System.out.println("Saving author" + author.getName() + "....");
authorRepostories.save(author);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
private void initWorks() {
}
#PostConstruct
public void start() {
initAuthors();
initWorks();
}
#Bean
public CqlSessionBuilderCustomizer sessionBuilderCustomizer(DataStaxAstraProperties astraProperties) {
Path bundle = astraProperties.getSecureConnectBundle().toPath();
return builder -> builder.withCloudSecureConnectBundle(bundle);
}
}
found the issue. Had to do with access rights. Java couldn't access the files because it was secured after changing the property of a file, it worked.
I know that I have to use ASyncTasks in order to make JSoup work for android, but all examples online illustrate that just by using random jsoup methods in the MainActivity.
I want to create a HTMLParser class which will contains a function for each element I want to parse but I can't seem to make it work.
My HTMLParser:
public class HTMLParser extends AsyncTask<Void, Void, Void> {
private Document doc;
#Override
protected Void doInBackground(Void... voids) {
try {
doc = Jsoup.connect("https://www.bodybuilding.com/exercises").get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<String> findMuscleGroups(){
ArrayList<String> muscleGroups = new ArrayList<>();
Elements section = doc.select("a");
if (section != null) {
for (Element exercise : section) {
if (exercise.hasText() && !muscleGroups.contains(exercise.text()) &&
exercise.attr("href").contains("exercises/muscle")) {
muscleGroups.add(exercise.text());
}
}
}
return muscleGroups;
}
}
In my MainActivity I want to be able to create a HTMLParser object and be able to use something like ArrayList = htmlParser.findMuscleGroups()
My MainActivity:
HTMLParser parser = new HTMLParser();
new HTMLParser().execute();
for (String muscleGroup : parser.findMuscleGroups()){
textView.setText(muscleGroup + "\n");
}
Which won't work. I'm well aware that it isn't supposed to work and there is something I'm missing but I hope you guys can point me in the right direction.
Solution:
Probably not the best, but it works so there's that
I've added this toHTMLParser class
public Document initializeDoc(){
try {
Document doc = Jsoup.connect("https://www.bodybuilding.com/exercises").get();
return doc;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
In MainActivity I've created
private volatile Document doc = null;
private volatile HTMLParser htmlParser;
variables, and added the following in the onCreate method
htmlParser = new HTMLParser();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
doc = htmlParser.initializeDoc();
}
});
try {
t.start();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
And needless to say, calling htmlParser.findMuscleGroups(doc) works as expected
You can see what i am talking about in this picture
I have an array called "statusLikers" under a class called "Status". I am trying to create a facebook/instagram like/unlike functionality on button click.
Now, before i move on from where i am, i am trying to figure out how to remove users from the array.
I know how to add to th array but i dont know how to delete from it.
The way i am going about it is like this
List<Object> likesPpl = status.getList("statusLikers");
JSONObject myObject = new JSONObject();
try {
myObject.put("statusLikers", currUser.getUsername());
} catch (JSONException e1) {
e1.printStackTrace();
}
likesPpl.removeAll(Arrays.asList(myObject));
but it does not seem to work, first i want to learn to remove items from the array before i create the if statements.
to remove data from an array of a Parse Tab
List<String> ary_users = new ArrayList<String>();
ParseQuery<ParseObject> queryPart1 = ParseQuery.getQuery("Channel");
queryPart1.whereEqualTo("objectId",channel_id);
queryPart1.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e==null) {
if (list.size()>0) {
ParseObject p = list.get(0);
if (p.getList("usersArray")!=null) {
ary_users = p.getList("usersArray");
}
else
{
ary_users = null;
}
if (ary_users!=null) {
if (ary_users.contains(frnd_objid)) {
ary_users.remove(frnd_objid);
p.put("usersArray",ary_users);
p.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException arg0) {
Toast.makeText(activity,frnd_name+ "is successfully removed in the channel"+channel_name,Toast.LENGTH_LONG).show();
}
});
}
}
}
}
}
});
}
Here "usersArray" is an Array of table "Channel" .And I am removing "frnd_objid" from the "usersArray"
I'm working on a Android application using the Google App-Engine to store and manage data for the application. Unfortunately I've run into a problem which I don't seem able to solve.
When a user creates a new account a new "Project" is created for them. This project contains tasks, and these tasks are stored in an ArrayList in the Project class. So, in the constructor of the project class everything is instantiated and and the Tasks are created from a text-file with data in Json-format using Gson2.2.2.
All of this works fine, and if I look in the datastore viewer in the appengine admin console everything looks good. Immediately after creating the account the user is logged on, and when the user logs on the Tasks needs to be sent to the Android-client. This is where it gets weird. When serializing the Tasks back to Json format, they seem to be uninitialized. All the string fields are empty, and the integers are all set to 0, but the correct number of Tasks are being serialized so the list is populated. This problem persists, until I manually shut down the Instance in GAE. When it is restarted with a new request the data is then serialized correctly to Json format and everything works fine. Obviously this is not good, I can't have the server shutdown it's instance every time a new user creates an account, just to be able to serve them the correct data. So, please help me solve this. I've been struggling with it quite a while now. Below is code that accurately reproduces the problem.
public class CreateData extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp){
if(req.getParameter("name").length() > 1){
PersistenceManager pm = PMF.get().getPersistenceManager();
User u = new User(req.getParameter("name"));
pm.makePersistent(u);
pm.close();
try {
resp.getWriter().print("User created with name "+req.getParameter("name"));
} catch (IOException e) {
e.printStackTrace();
}
}else if(req.getParameter("name").length() <= 1){
try {
resp.getWriter().print("Please supply a name with at least 2 characters");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
resp.sendError(400);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The User class
public class User {
public #interface Skip {
// Field tag only annotation
}
#PrimaryKey
#Persistent
private String name;
#Persistent
private ArrayList<DataType> data;
public User(String name) {
this.name = name;
data = new ArrayList<DataType>();
createDataFromJSON();
}
public String getDatasAsJSON(){
Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy(Key.class)).create();
Type taskType = new TypeToken<List<DataType>>(){}.getType();
String json = gson.toJson(this.data, taskType);
return json;
}
public void createDataFromJSON() {
FileReader fr = null;
try {
fr = new FileReader(new File("WEB-INF/defaults.json"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (fr != null) {
Type taskType = new TypeToken<List<DataType>>(){}.getType();
data = new Gson().fromJson(fr, taskType);
}
}
public class MyExclusionStrategy implements ExclusionStrategy {
private final Class<?> typeToSkip;
private MyExclusionStrategy(Class<?> typeToSkip) {
this.typeToSkip = typeToSkip;
}
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz == typeToSkip);
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Skip.class) != null;
}
}
}
The DataType class
public class DataType {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
#Persistent
private String name;
#Persistent
private int points;
#Persistent
private int unique;
public DataType() {
}
public DataType(String name, int points, int unique){
this.name = name;
this.points = points;
this.unique = unique;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public int getUnique() {
return unique;
}
public void setUnique(int unique) {
this.unique = unique;
}
}
Servlet for getting the data
public class GetData extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp){
String name = req.getParameter("name");
PersistenceManager pm = PMF.get().getPersistenceManager();
User u = null;
try{
u = pm.getObjectById(User.class, name);
}catch(JDOObjectNotFoundException e){
try {
resp.sendError(404);
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(u != null){
String response = u.getDatasAsJSON();
try {
resp.getWriter().print(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And the JSON data
[
{
"name": "Hug",
"unique": 1,
"points": 20
},
{
"name": "Tug",
"unique": 2,
"points": 40
},
{
"name": "Rug",
"unique": 3,
"points": 50
},
{
"name": "Jug",
"unique": 4,
"points": 100
},
{
"name": "Smug",
"unique": 5,
"points": 20
}
]
So, creating a new User with name "Arne" works fine and the objects are created in the HDR. Asking for the objects back from the datastore as Json yields this response
[{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0},{"points":0,"unique":0}]
upon restarting the server instance the same request gives this response
[{"name":"Hug","points":20,"unique":1},{"name":"Tug","points":40,"unique":2},{"name":"Rug","points":50,"unique":3},{"name":"Jug","points":100,"unique":4},{"name":"Smug","points":20,"unique":5}]
Sorry for the long post, but hopefully somebody is able to point out to me what I'm doing wrong. Many thanks in advance!
Best regards,
Ivar
To bad nobody seem to be able to answer this, though I've found a work around. I still think this needs a proper solution, but at least I've got it working now by looping through all the objects and assigning a temporary variable with the value from a field in the object. This seems to force them to initialize, and the returned JSON is actually populated with the correct fields.
public class GetData extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse resp){
String name = req.getParameter("name");
PersistenceManager pm = PMF.get().getPersistenceManager();
User u = null;
try{
u = pm.getObjectById(User.class, name);
}catch(JDOObjectNotFoundException e){
try {
resp.sendError(404);
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(u != null){
//By adding this seemingly pointless loop
//the objects will actually return populated fields
//when converted back to JSON
for(DataType dt : u.getData()){
String temp = dt.getName();
}
String response = u.getDatasAsJSON();
try {
resp.getWriter().print(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}