I want to get information from baidu music web api. I use below tow link:
http://openapi.baidu.com/rest/2.0/music/billboard/billlist?page_size=50×tamp=2016-09-22+18%3A47%3A54&sign=b2e34bd4b6c19a065d5a7e49e591a41b&session_key=9mzdDcHtDENrxP3Spvk7ZFbNHNijT8l8fN%2BfI%2Fe3U5rh3U5g%2FDVvjZyqB48aJaYO5qaqw4JbugF79hgAQ%2FGBIixUSuaP&type=21&page_no=1
http://openapi.baidu.com/rest/2.0/music/billboard/billlist?page_size=50×tamp=2016-09-26+17%3A42%3A18&sign=62cc904c8ff2817280f699a4bd4b6496&session_key=9mzdDcHtDENrxP3Spvk7ZFbNHNijT8l8fN%2BfI%2Fe3U5rh3U5g%2FDVvjZyqB48aJaYO5qaqw4JbugF79hgAQ%2FGBIixUSuaP&type=23&page_no=1
only type is different. one is 23 and another is 21. For return jason: one is billboard21, another is billboard23. If I want to use retrofit2 to accessa api and parse return jason, should I define two different java class to handler this two different return? In face, there is about 17 type, how can I handle this case if don't want to create 17 java classes?
my access api is:
#GET("/rest/2.0/music/billboard/billlist")
Call<BaiduBillListContainer> getBillList(#Query("timestamp") String timestamp,
#Query("type") String type,
#Query("sign") String sign,
#Query("session_key") String sessionkey,
#Query("page_size") String pagesize,
#Query("page_no") String pageno);
BaiduBillListContainer.java define:
public class BaiduBillListContainer implements Serializable {
BaiduBillList billboard21;
public BaiduBillList getBillBoardInfo() {
return billboard21;
}
public void setBillBoardInfo(BaiduBillList billBoardInfo) {
this.billboard21 = billBoardInfo;
}
}
it cannot used to get billboard23 return. Any one can help me about this question? thanks very much.
Try this:
public class BaiduBillListContainer implements Serializable {
Map<String,BaiduBillList> billboard;
public Map<String,BaiduBillList> getBillBoardInfo() {
return billboard;
}
public void setBillBoardInfo(Map<String,BaiduBillList> billBoardInfo) {
this.billboard= billBoardInfo;
}
}
Then call billboard from map like:
Map<String,BaiduBillList> getBBData=response.body();
BaiduBillList receivedBBList=getBBData.values().toArray()[0]
Related
I would like to parse an XML file using Java. I found some tutorials online but no one tells about parsing subtags and using them as objects' attributes.
I tried to use the code found here.
But it doesn't show how to treat tags that are inside other tags. Let me show you an example:
<lotto>
<cig>Z9E1CD9F58</cig>
<strutturaProponente>
<codiceFiscaleProp>00222010654</codiceFiscaleProp>
<denominazione>COMUNE DI PERDIFUMO</denominazione>
</strutturaProponente>
</lotto>
lotto is my main tag, which contains all the data I need. In my code, I created a class called in the same way. Its attributes are the same as the tags contained in the main one (cig, strutturaProponente,...).
I would like strutturaProponente to become a class. I don't know how to parse tags which are inside of tag strutturaProponente as well as the tag cig.
Thank you for your patience and consideration.
Well, let me see if I understood. Would you like the representantion in code of XML, I believe that class would be like something this.
public class Loto
{
private String cig;
public String getCig()
{
return cig;
}
public void setCig(String value){
cig = value;
}
}
public class StrutturaProponente
{
private int codiceFiscaleProp;
private string denominazione;
public int getCodiceFiscaleProp()
{
return cig;
}
public void setCodiceFiscaleProp(int value){
codiceFiscaleProp = value;
}
public String getDenominazione()
{
return denominazione;
}
public void setDenominazione(String value){
denominazione = value;
}
}
I hope have helped.
I'm trying make reuse of single retrofit api call by inherit from a base response class.
However I'm not able to do it.
I will try to make myself clear with example (It's not a concrete scenario. I'm just trying to figure out the main idea):
Having this response objects and api service:
public class UserDetailsResponse
{
private int userId;
}
public class ExtendedUserDetailsResponse extends UserDetailsResponse
{
private int userAdditionalId;
}
interface APIService
{
#GET("/UserDetails/")
Call<UserDetailsResponse> getUserDetails(#Query("id") String userId);
}
Is there a way of using getUserDetails api with ExtendedUserDetailsResponse object?
This one gives me compilation error:
mService.getUserDetails("123").enqueue(new Callback<ExtendedUserDetailsResponse>()
{
#Override
public void onResponse(Call<ExtendedUserDetailsResponse> call, Response<ExtendedUserDetailsResponse> response)
{
}
#Override
public void onFailure(Call<ExtendedUserDetailsResponse> call, Throwable t)
{
}
});
How can I solve this? or at least something similar to this, without using a new api call for the specific derived class?
Thanks!
You get an error because ExtendedUserDetailsResponse is a UserDetailsResponse, however, UserDetailsResponse is not necessarily an ExtendedUserDetailsResponse.
In order to make it generic, sign your method this way
Call< ExtendedUserDetailsResponse > getUserDetails(#Query("id") String userId);
Then ExtendedUserDetailsResponse will have access to userId
Remember to expose userId with getters and setters so that it get parsed.
You are getting compilation error because you are using the wrong callback object:
Just change this line:
Call<UserDetailsResponse> getUserDetails(#Query("id") String userId);
to
Call<ExtendedUserDetailsResponse> getUserDetails(#Query("id") String userId);
Or depending on the response change the object in the callback
Note that ExtendedUserDetailsResponse will have userId so you can use ExtendedUserDetailsResponse even if the server returns object of type UserDetailsResponse or ExtendedUserDetailsResponse.
Hi I hope someone here can help me, I am working in an android app, I already serialize the following gson object
Screenshot:
the jsonobject has many subclasses like:
PreferencialaboraEstudio,Preferencialaboralarea, and more classes,
I transfer this gson object from an activity to a new activity, in order to deserialize this object I have implemented the following code in the new activity:
Intent intent = getIntent();
String Postulado = intent.getStringExtra("Postulado");//Postulado from extra is actually a gson object
Candidato candidato = gson.fromJson(Postulado, Candidato.class);
CandidatoPreferenciaLaboralEstado preflaboraledo = gson.fromJson(Postulado, CandidatoPreferenciaLaboralEstado.class);
I have the problem in CandidatoPreferenciaLaboralEstado, as you can see in the picture there are two items of this type class in the gson object, but my code only returns the first item and not the second one, is there a way to get all the items of this type "CandidatoPreferenciaLaboralEstado" from the gson?
Thank you very much for your time and assistance in this matter.
Not sure how your root model is, but you can have something like this:
public class Postulado {
private CandidatoPreferenciaLaboralEstado candidatoPreferenciaLaboralEstado;
private CandidatoSoftware candidatoSoftware;
public class CandidatoPreferenciaLaboralEstado {
private List<CandidatoPrefAttributes> candidatoAttributesList;
public class CandidatoPrefAttributes {
private Integer cveCandidato;
private Integer cveCandidatoPreferenciaLaboralEstado;
//More
}
}
public class CandidatoSoftware {
private List<CandidatoSoftwareAttributes> candidatoAttributesList;
public class CandidatoSoftwareAttributes {
private Integer cveCandidato;
private Integer cveCandidatoSoftware;
//More
}
}
}
With respective getters.
Also looks that the candidates (CandidatoPreferenciaLaboralEstado and CandidatoSoftware) and Candidate Preferences are very similar, maybe you can unify that models to one (Candidate and CandidatePrefferences) and use multiple serialized names like:
#SerializedName(value="candidatoPreferenciaLaboralEstado", alternate={"candidatoSoftware"})
Hope this can help you!
I started using Retrofit recently. I don't know much about it. I have googled this issue and no answers suite my problem.
This is JSON response
{
"results": [
{
"description_eng": "This is second time testing",
"img_url": "-",
"title_eng": "Second test"
},
{
"description_eng": "Hello 1 2 3, I am testing.",
"img_url": "https://fbcdn-sphotos-f-a.akamaihd.net/hphotos-ak-xpa1/t31.0-8/s720x720/10838273_816509855058935_6428556113200361121_o.jpg",
"title_eng": "Test"
}
]
}
This is Feed Class
public class Feed {
public List<Results> results;
class Results{
String description_eng,img_url,title_eng;
}
}
This is the interface
public interface GetApi {
#GET("/api.json")
public void getData(Callback<List<Feed>> response);
}
I got json_illegal_syntax Exception.
This is how I solved this problem, by creating empty constructors.
Feed.class
public class Feed{
private List<Result> results;
public Feed(){}
public List<Result> getFeed(){
return this.results;
}
public void setFeed(List<Result> results) {
this.results = results;
}
}
Result.class
public class Result{
private String description_eng;
private String img_url;
private String title_eng;
public Result(){}
//getters and setters
}
GetApi.class
public interface GetApi {
#GET("/api.json")
public void getData(Callback<Feed> response);
}
Retrofit uses Gson by default to convert HTTP bodies to and from JSON. If you want to specify behavior that is different from Gson's defaults (e.g. naming policies, date formats, custom types), provide a new Gson instance with your desired behavior when building a RestAdapter.
Gson can not automatically deserialize the pure inner classes since their no-args constructor also need a reference to the containing Object which is not available at the time of deserialization. You can address this problem by either making the inner class static or by providing a custom InstanceCreator for it. Here is an example:
public class A {
public String a;
class B {
public String b;
public B() {
// No args constructor for B
}
}
}
NOTE: The above class B can not (by default) be serialized with Gson.
You should read more about GSON library
#Ye Min Htut Actually, even better is to write Feed class with generics.
public class FeedList<T>{
private List<T> feeds;
public Feed() {
}
public List<T> getFeed(){
return this.feeds;
}
public void setFeed(List<T> results) {
this.feeds = feeds;
}
}
and if there is something similar with only one object, than you can remove List part and get/set single object.
Now you can call FeedList<Result> or with whatever object you want.
GetApi.class
public interface GetApi {
#GET("/api.json")
public void getData(Callback<FeedList<Result>> response);
}
#Ye Min Htut I will suggest you to make Model/POJO classes using ROBOPOJO Generator It will generate All model classes for you, you don't need to make it by your self, Will also help you in future while creating model class. It just need JSON string and click will make your job done
I'm asking this question: instread of giving a string, a int and so on, can we push a custom object during the creation fo a new Intent?
newActivity.PutExtra("JsonDataResult", business.getJSON());
In fact I have one object constructed thanks to a JSON (from webrequest) , I parse it and I put it on an object.
At this point I'm passing the string returned from the webrequest to another intent but the parsing takes a long time tu be done, so it could be super-cool the ability to pass custom object with intent.
EDIT : I'm using monodroid / xamarin, so
Android.OS.IParcelable cannot be implemented,
Java.IO.ISerializable cannot be implemented.
You can either let your custom classes implement Parcelable (Google says its faster, but you have to do more coding) or Serializable.
Then add your objects to a bundle (or to the "extra"):
Bundle b = new Bundle()
b.putParcelable("myObject",myObject);
b.putSerializable("myObject",myObject);
For info to Parcelablecheckout this
And if you're interested in the difference between Parcelable and Serializable in more detail check out this
I personally prefer the usage of Serializable for simple object-passing, since the code ist not spoiled with so much code.
Edit: ok isn't your question very similar to this then?
As you've specified you're using Monodroid, it looks like it's not straightforward. I did a quick search and found this forum post
Which listed the following solutions to this problem in Monodroid:
Store the custom Object to be passed as a global variable somewhere, and just read it from your second activity
Which is a bit messy and bad practice, but would work.
Or
serialize your class to a string and send the string to the second Activity
Which will be a little more hard work, but better practice
This is an example how to create a Parcelable class:
public class Person implements Parcelable {
private String name;
private String surname;
private String email;
// Get and Set methods
#Override
public int describeContents() {
return hashCode();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(surname);
dest.writeString(email);
}
// We reconstruct the object reading from the Parcel data
public Person(Parcel p) {
name = p.readString();
surname = p.readString();
email = p.readString();
}
public Person() {}
// We need to add a Creator
public static final Parcelable.Creator<person> CREATOR = new Parcelable.Creator<person>() {
#Override
public Person createFromParcel(Parcel parcel) {
return new Person(parcel);
}
#Override
public Person[] newArray(int size) {
return new Person[size];
}
};
Give a look here if you want to use Parcelable.