I'm using Robospice with Retrofit ans ORMLite modules. Retrofit part working good. I have City model for Retrofit:
City.java:
public class City {
public int city_id;
public String name;
#SuppressWarnings("serial")
public static class List extends ArrayList<City> {
}
}
I'm taking this model from server by GET-request:
MyApi.java
public interface MyAPI {
#GET("/cities")
City.List getCities();
}
This part works fine by calling this method:
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
and listener:
public final class ListCityRequestListener implements RequestListener<City.List> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Toast.makeText(RegisterActivity.this, "failure", Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestSuccess(final City.List result) {
Toast.makeText(RegisterActivity.this, "success", Toast.LENGTH_SHORT).show();
updateCities(result);
}
}
At this time i want to download city list once from server and store this list into sqlitedb by ORMLite module. I've created ORMLite model:
City.java
#DatabaseTable(tableName = "city")
public class City {
public final static String DB_CITY_ID_FIELD_NAME = "id";
public final static String DB_CITY_NAME_FIELD_NAME = "name";
#DatabaseField(canBeNull = false, dataType = DataType.INTEGER, columnName = DB_CITY_ID_FIELD_NAME)
int id;
#DatabaseField(canBeNull = false, dataType = DataType.STRING, columnName = DB_CITY_NAME_FIELD_NAME)
private String name;
public City() {
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("id = ").append(id);
sb.append(", ").append("name = ").append(name);
return sb.toString();
}
}
My RetrofitSpiceService.java looks like this:
public class RetrofitSpiceService extends RetrofitGsonSpiceService {
private final static String BASE_URL = "http://example.com/api/v1";
private final static UserFunctions userFunctions = new UserFunctions();
#Override
public CacheManager createCacheManager(Application application) throws CacheCreationException {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
// add persisted classes to class collection
classCollection.add( City.class );
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper( application, "sample_database.db", 1 );
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory( application, databaseHelper, classCollection );
cacheManager.addPersister( inDatabaseObjectPersisterFactory );
return cacheManager;
}
#Override
protected Builder createRestAdapterBuilder() {
Builder mBuilder = super.createRestAdapterBuilder();
mBuilder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
if (userFunctions.isUserLoggedIn()) {
request.addHeader("Authorization", userFunctions.getToken());
}
}
});
return mBuilder;
}
#Override
public void onCreate() {
super.onCreate();
addRetrofitInterface(MyAPI.class);
}
#Override
protected String getServerUrl() {
return BASE_URL;
}
}
I can't understand how can i store and read data from my City database? How do i need to change RetrofitSpiceService? I want download data by Retrofit and store it to database by ORMLite. My CacheManager is correct, i.e. will work properly? Maybe I misunderstand how the module Robospice-ORMLite works?
Thanks a lot!
When you make execute() call with cache key and duration Robospice will store your response into database.
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
All following requests during one minute will get data from this cache, and then it makes network call. If you want to get data only from cache take a look on getSpiceManager().getFromCache() method. I think it's what you are looking for.
Related
I am developing the project in mvvm architecture. Here I have a class like create profile and also another class like edit profile. Edit profile is a fragment class. here I created a same view model class for both the create profile and edit profile fragment classes.In edit profile class when I call view model class getting null pointer exception.
In Edit Profile Fragment Class I am calling the view model class
public class EditProfileFragment extends BaseFragment {
private UserService userService;
private String eId;
private final static String TAG = "EditProfile";
#Override
protected int getFragmentLayoutID() {
return R.layout.activity_create_profile;
}
#Override
protected boolean isSubscribedToEvents() {
return true;
}
#Override
protected Class<ProfileVM> getVMClass() {
return ProfileVM.class;
}
#Override
protected int getVMVariableId() {
return BR.profileVM;
}
#Override
protected void init() {
userService = getApiClient().create(UserService.class);
ProfileVM profileVM = (ProfileVM) getViewModel();
UserDTO userDTO = getUserDao().getUserDetails();
eId = userDTO.getId();
Log.d(TAG,"editprofileenigma"+eId);
Log.d(TAG,"userdtoedit"+userDTO);
userService.getUserProfile(eId);// this is the api call
profileVM.user.setValue(userDTO); // here iam getting null pointer exception
profileVM.individual.setValue(getUserDao().getUserIndividual());
profileVM.individualProfile.setValue(getUserDao().getIndividualProfile());
profileVM.individualAttributePermission.setValue(getUserDao().getIndividualAttributePermission());
}
}
My View Model Class
#Bindable
public MutableLiveData<String> heading = new MutableLiveData<>("Create Profile");
#Bindable
public MutableLiveData<UserDTO> user = new MutableLiveData<>(new UserDTO());
#Bindable
public MutableLiveData<Individual> individual = new MutableLiveData<>(new Individual());
#Bindable
public MutableLiveData<Boolean> isDemographicExpanded = new MutableLiveData<>(true);
#Bindable
public MutableLiveData<Boolean> isLiveNInterestExpanded = new MutableLiveData<>(true);
#Bindable
public MutableLiveData<IndividualProfile> individualProfile = new MutableLiveData<>(new IndividualProfile());
#Bindable
public MutableLiveData<IndividualAttributePermission> individualAttributePermission = new MutableLiveData<>(new IndividualAttributePermission());
#Bindable
public MutableLiveData<ProfileSwitchModel> profileSwitchModel = new MutableLiveData<>(new ProfileSwitchModel(new IndividualAttributePermission()));
private Individual getIndividual() {
return individual.getValue()==null? new Individual() : individual.getValue();
}
private IndividualProfile getIndividualProfiles() {
return individualProfile.getValue()==null? new IndividualProfile() : individualProfile.getValue();
}
private IndividualAttributePermission getIndividualAttributePermissions() {
return individualAttributePermission.getValue()==null? new IndividualAttributePermission() : individualAttributePermission.getValue();
}
I created a room database following this guide from code labs It makes use of a repository to:
A Repository manages query threads and allows you to use multiple backends. In the most common example, the Repository implements the logic for deciding whether to fetch data from a network or use results cached in a local database.
I followed the guide and i'm now able to create the entity's & retrieve the data. I even went further and created another whole entity outside the scope of the guide.
However I can't find many resources that use this MVVM(?) style so am struggling as to really under stand the repository. For now I want to update a field. Just one, as if I am able to manage that the rest should be similar.
I want to update a field called dartshit and I have the dao method created for this:
#Query("UPDATE AtcUserStats SET dartsHit = :amount WHERE userName = :userName")
void UpdateHitAmount(int amount, String userName);
I have one repository which I assumed I use for all entities:
public class UsersRepository {
private UsersDao mUsersDao;
private AtcDao mAtcDao;
private LiveData<List<Users>> mAllUsers;
private LiveData<List<AtcUserStats>> mAllAtc;
private AtcUserStats mAtcUser;
UsersRepository(Application application) {
AppDatabase db = AppDatabase.getDatabase(application);
mUsersDao = db.usersDao();
mAtcDao = db.atcDao();
mAllUsers = mUsersDao.fetchAllUsers();
mAllAtc = mAtcDao.getAllAtcStats();
}
LiveData<List<Users>> getAllUsers() {
return mAllUsers;
}
LiveData<List<AtcUserStats>> getAllAtcStats() {
return mAllAtc;
}
LiveData<AtcUserStats> getAtcUser(String username) {
return mAtcDao.findByName(username);
}
public void insert (Users user) {
new insertAsyncTask(mUsersDao).execute(user);
}
public void insertAtc (AtcUserStats atc) {
new insertAsyncAtcTask(mAtcDao).execute(atc);
}
private static class insertAsyncTask extends AsyncTask<Users, Void, Void> {
private UsersDao mAsyncTaskDao;
insertAsyncTask(UsersDao dao) {
mAsyncTaskDao = dao;
}
#Override
protected Void doInBackground(final Users... params) {
mAsyncTaskDao.insertNewUser(params[0]);
return null;
}
}
private static class insertAsyncAtcTask extends AsyncTask<AtcUserStats, Void, Void> {
private AtcDao mAsyncTaskDao;
insertAsyncAtcTask(AtcDao dao) {
mAsyncTaskDao = dao;
}
#Override
protected Void doInBackground(final AtcUserStats... params) {
mAsyncTaskDao.insertNewAtcUser(params[0]);
return null;
}
}
}
My question is how do I create a AsyncTask for the update query I am trying to run in this repository?
Here is what I have so far by broadly copying the insert repository methods:
private class updateHitAsyncTask {
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
protected Void doInBackground(int amount, String name) {
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
Which is incorrect is that I'm getting a llegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. error. But i thought this AsyncTask is suppose to take care of this?
Here is my update method in my view model, which is reporting 0 errors:
void updateHitAmount (int amount, String name) {
mRepository.updateAtcHits(amount, name);
}
and here is the UI code where im actually trying to tie all these together, I suspect there must be a better way that using onChanged for simply updating a field but again I am struggling to come across any advice on google with the repository approach:
private void callOnChanged() {
mAtcViewModel = ViewModelProviders.of(this).get(AtcViewModel.class);
mAtcViewModel.getAllUsers().observe(this, new Observer<List<AtcUserStats>>() {
#Override
public void onChanged(#Nullable final List<AtcUserStats> atc) {
// Update the cached copy of the users in the adapter.
for (int i = 0; i < atc.size(); i++) {
if (atc.get(i).getUserName().equals(mUser)) {
mAtcViewModel.updateHitAmount(55, mUser);
//atc.get(i).setDartsHit(55);
Log.d("id", String.valueOf(userSelected.getId()));
}
}
}
});
How can I update fields using this approach on the background thread?
Figured it out due to this answer here. It was mostly because of my lack of understanding of AsyncTask. Essentially I needed to create an object and pass the data that way and then execute in the background:
private static class MyTaskParams {
int amount;
String name;
MyTaskParams(int amount, String name) {
this.amount = amount;
this.name = name;
}
}
public void updateAtcHits (int amount, String name) {
MyTaskParams params = new MyTaskParams(amount,name);
new updateHitAsyncTask(mAtcDao).execute(params);
}
private class updateHitAsyncTask extends AsyncTask<MyTaskParams,Void,Void>{
private AtcDao mAsyncTaskDao;
public updateHitAsyncTask(AtcDao mAtcDao) {
mAsyncTaskDao = mAtcDao;
}
#Override
protected Void doInBackground(MyTaskParams... myTaskParams) {
int amount =myTaskParams[0].amount;
String name = myTaskParams[0].name;
mAsyncTaskDao.UpdateHitAmount(amount, name);
return null;
}
}
I am using Firebase.
1. Question:
I create a Key with:
final String CHATS_CHILD = "chats/" + mFirebaseDatabaseReference.push().getKey();
mFirebaseDatabaseReference.child(CHATS_CHILD).push().setValue("and so on...");
The result you see in the picture. Now I created a key with childrens in Firebase but how to I get the key into my android app? (I mean the first key, after Chats)
2. Qestion is similar
You see the databe in my Picture. How can I get the first key after chats, when I search after the text? So for example I want the key which has as child the Text "Test1"
How to do that?
Thanks in advance.
I think you should flatten your data in order to get message key and chat key using just message text. You can keep actual messages in a separate path (like "messages") and keep only message keys inside related chat's path, as shown in the following structure:
Create Chat class:
public class Chat {
private Map<String, Boolean> messageKeys;
public Chat() {
// Default constructor required for calls to DataSnapshot.getValue(Chat.class)
}
public Chat(Map<String, Boolean> messageKeys) {
this.messageKeys = messageKeys;
}
public Map<String, Boolean> getMessageKeys() {
return messageKeys;
}
public void setMessageKeys(Map<String, Boolean> messageKeys) {
this.messageKeys = messageKeys;
}
}
..and Message class:
public class Message {
private String chatKey;
private String text;
private long time;
public Message() {
// Default constructor required for calls to DataSnapshot.getValue(Message.class)
}
public Message(String chatKey, String text, long time) {
this.chatKey = chatKey;
this.text = text;
this.time = time;
}
public String getChatKey() {
return chatKey;
}
public void setChatKey(String chatKey) {
this.chatKey = chatKey;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
}
Then query messages and find those whose text field is equal to the term you are searching, for example "Test1":
DatabaseReference chatsRef = FirebaseDatabase.getInstance().getReference("chats");
DatabaseReference messagesRef = FirebaseDatabase.getInstance().getReference("messages");
messagesRef.orderByChild("text").equalTo("Test1").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String messageKey = child.getKey();
Message message = child.getValue(Message.class);
String chatKey = message.getChatKey();
// Now you have both the chatKey and the messageKey...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
Creating a new chat and its first message would look like below in this case (can be considered as answer to your first question):
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
String chatKey = rootRef.push().getKey();
String messageKey = rootRef.push().getKey();
Message newMessage = new Message(chatKey, "My message trial", Calendar.getInstance().getTimeInMillis());
Map<String, Boolean> messageKeys = new LinkedHashMap<>();
messageKeys.put(messageKey, true);
Chat newChat = new Chat(messageKeys);
rootRef.child("messages").child(messageKey).setValue(newMessage);
rootRef.child("chats").child(chatKey).setValue(newChat);
Retrieving all messages that belongs to a chat whose key is known:
String chatKey = "chatKey1"; // Get it somehow
DatabaseReference messagesRef = FirebaseDatabase.getInstance().getReference("messages");
messagesRef.orderByChild("chatKey").equalTo(chatKey).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Message> messageList = new ArrayList<>();
for (DataSnapshot child : dataSnapshot.getChildren()) {
String messageKey = child.getKey();
Message message = child.getValue(Message.class);
messageList.add(message);
}
// Now you have all messages in messageList...
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
in additional to answer of Mehmed: Firebase DB supports not only setting/retrieving single fields, but also whole the objects of some class.
In the example below I define class MyChat, create few objects of it and put them into Firebase DB. Then I retrieve all of them (as objects, not just strings) and put them into ArrayList.
FirebaseDatabase frDb = FirebaseDatabase.getInstance();
DatabaseReference mFirebaseDatabaseReference = frDb.getReference();
final String CHATS_CHILD = "chats/theChat" ; //+ mFirebaseDatabaseReference.push().getKey();
// Create 3 objects of class MyChat
MyChat chat1 = new MyChat("Test1", "21-Sep-2017");
MyChat chat2 = new MyChat("Test21", "26-Sep-2017");
MyChat chat3 = new MyChat("TestB", "28-Sep-2010");
//Add all the chats to Firebase DB
mFirebaseDatabaseReference.child(CHATS_CHILD).push().setValue(chat1);
mFirebaseDatabaseReference.child(CHATS_CHILD).push().setValue(chat2);
mFirebaseDatabaseReference.child(CHATS_CHILD).push().setValue(chat3);
// Here we will retrieve all the chats and put them to array
// Declare array to keep results
final ArrayList<MyChat> arr1 = new ArrayList<MyChat>();
//Listener
ChildEventListener chEvLst = mFirebaseDatabaseReference.child("chats").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot ds1 : dataSnapshot.getChildren()) {
MyChat chatRes = ds1.getValue(MyChat.class);
Log.i("Next chat text:",chatRes.getmText());
Log.i("Next chat date:",chatRes.getmText());
arr1.add(chatRes); // retrieve and save chats to array
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
And this is class MyChat
public class MyChat {
String mText = "Test1"; // default values...
String mDate = "26-Sep-2017";
// *** MUST TO HAVE EMPTY CONSTUCTOR FOR FIREBASE !!! ***
public MyChat() {
}
// Second constructor
public MyChat(String mText, String mDate) {
this.mText = mText;
this.mDate = mDate;
}
// *** MUST TO HAVE ALL GETTERS/SETTERS FOR FIREBASE!!! ***
// Getters/setters
public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
}
public String getmDate() {
return mDate;
}
public void setmDate(String mDate) {
this.mDate = mDate;
}
}
And this is resulting DB structure :
Best regards!
I am able to get data from database using retrofit and REST api but facing errors in Posting data. Post works using postman but not through retrofit.I have been unable to locate the error.I have tried changing endpoint, that is, "rest" and "rest/" but still get not found error.
ApiView of Post in Django RESTful api: view.py
def post(self,request):
serializer =table_restSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'results':serializer.data},status=201)
return Response(serializer.errors, status=404)
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^rest',views.restSerializer.as_view())
]
urlpatterns = format_suffix_patterns(urlpatterns)
serializer.py:
class table_restSerializer(serializers.ModelSerializer):
class Meta:
model = table_rest
fields = '__all__'
My android code:
Interface
public interface ApiInterface {
#GET("rest")
Call<CustomViewResponse> getJsonFromSid();
#POST("rest")
Call<CustomViewResponse> createTask(#Body CustomViewHolder task);
}
CustomViewHolder class:
public class CustomViewHolder {
#SerializedName("id")
private Integer id;
#SerializedName("tt")
private String tt;
#SerializedName("varr")
private Integer varr;
#SerializedName("edi")
private String edi;
public CustomViewHolder(String tt, Integer varr, String edi){
this.tt = tt;
this.varr = varr;
this.edi = edi;
}
public Integer getid(){
return id;
}
/*public void setid(Integer id){
this.id = id;
}*/
public String gettt()
{
return tt;
}
public void settt(String tt){
this.tt = tt;
}
public Integer getvarr(){
return varr;
}
public void setvarr(Integer varr){
this.varr = varr;
}
public String getedi(){
return edi;
}
public void setedi(String edi){
this.edi = edi;
}
}
CustomViewResponse class
public class CustomViewResponse {
#SerializedName("results")
private List<CustomViewHolder> results;
public List<CustomViewHolder> getResults(){
return results;
}
}
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.sid_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
ApiInterface apiService1 = ApiClient.getClient().create(ApiInterface.class);
Call<CustomViewResponse> call = apiService.getJsonFromSid();
CustomViewHolder cc = new CustomViewHolder("my task title",22,"a string");
call.enqueue(new Callback<CustomViewResponse>() {
#Override
public void onResponse(Call<CustomViewResponse> call, Response<CustomViewResponse> response) {
int statuscode = response.code();
List<CustomViewHolder> customViewHolders = response.body().getResults();
recyclerView.setAdapter(new AdapterSid(customViewHolders, R.layout.list_item_sid, getApplicationContext()));
}
#Override
public void onFailure(Call<CustomViewResponse> call, Throwable t) {
Log.e("TAG main", t.toString());
}
});
call1.enqueue(new Callback<CustomViewResponse>() {
#Override
public void onResponse(Call<CustomViewResponse> call1, Response<CustomViewResponse> respo) {
int statuscode = respo.code();
Log.d("Message", "code..."+respo.code() + " message..." + respo.message());
CustomViewResponse respon = respo.body();
if (respon == null){
Log.e("Error",""+statuscode+ "......"+ respo.message()+"....null body");
}
}
#Override
public void onFailure(Call<CustomViewResponse> call1, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
Following is my table structure:
class table_rest(models.Model):
tt = models.CharField(max_length=10,default = 12)
varr = models.IntegerField(default=30)
edi = models.CharField(max_length=1000,default='44')
def __str__(self):
return self.tt
Using postman my Json body which gets successfully saved is :
{
"tt": "hello",
"varr": 911,
"edi": "emergency. Can't find solution"
}
Please add an extra URL.
urlpatterns = [
url(r'^admin/', admin.site.urls), # Any URL starting with admin(ex: http://testdomainname.com/admin/xyz)
url(r'^rest/$',views.restSerializer.as_view()), # Any URL starting with only rest(ex: http://testdomainname.com/rest/)
url(r'^$',views.restSerializer.as_view()), # Any empty URL with '' (ex: http://testdomainname.com/)
]
First I included the url pattern as suggested by Dinesh Mandepudi. Then I made changes to my regex in retrofit. It was url issue that I was not confronting when using postman. I just added '/' at the beginning of my post regex.
public interface ApiInterface {
#GET("/rest")
Call<CustomViewResponse> getJsonFromSid();
#POST("/rest/")
Call<CustomViewResponse> createTask(#Body CustomViewHolder task);
}
Also a silly mistake is I was trying to add a string of 13 length in the database column while I had set the limit to 10.
I am trying to pull data from class in another class and populate a JPanel with the data, but it is not working for some reason.
Here is the full restConnector class where I pull the JSON data.
As far as I know this works fine.
public class restConnector {
private static final Logger LOGGER = LoggerFactory.getLogger(restConnector.class);
private static final restConnector INSTANCE = new restConnector();
public static restConnector getInstance() {
return restConnector.INSTANCE;
}
private restConnector(){
}
private static String user = "ss";
private static String pwd = "ee
public static String encode(String user, String pwd) {
final String credentials = user+":"+pwd;
BASE64Encoder encoder = new sun.misc.BASE64Encoder();
return encoder.encode(credentials.getBytes());
}
//Open REST connection
public static void init() {
restConnector.LOGGER.info("Starting REST connection...");
try {
Client client = Client.create();
client.addFilter(new LoggingFilter(System.out));
WebResource webResource = client.resource("https://somewebpage.com/
String url = "activepersonal";
ClientResponse response = webResource
.path("api/alerts/")
.queryParam("filter", ""+url)
.header("Authorization", "Basic "+encode(user, pwd))
.header("x-api-version", "1")
.accept("Application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
}else{
restConnector.LOGGER.info("REST connection STARTED.");
}
String output = response.getEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new MyNameStrategy());
try {
List<Alert> alert = mapper.readValue(output, new TypeReference<List<Alert>>(){});
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
}
}
However, when I try to pull the data in another class it gives me just null values from the system.out.print inside refreshData() method. Here is the code that is supposed to print the data
public class Application{
Alert alerts = new Alert();
public Application() {
refreshData();
}
private void initComponents() {
restConnector.init();
refreshData();
}
private void refreshData() {
System.out.println("appalertList: "+alerts.getComponentAt(0));
}
}
Here is my Alert class
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(Include.NON_EMPTY)
public class Alert {
private int pasID;
private String status;
private boolean shared;
private String header;
private String desc;
public int getPasID() {
return pasID;
}
public void setPasID(int pasID) {
this.pasID = pasID;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public boolean isShared() {
return shared;
}
public void setShared(boolean shared) {
this.shared = shared;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("\n***** Alert Details *****\n");
sb.append("PasID="+getPasID()+"\n");
sb.append("Status="+getStatus()+"\n");
sb.append("Shared="+isShared()+"\n");
sb.append("Header="+getHeader()+"\n");
sb.append("Description="+getDesc()+"\n");
sb.append("*****************************");
return sb.toString();
}
public String getComponentAt(int i) {
return toString();
}
}
I'm kind a lost with this and been stuck here for a couple of days already so all help would be really appreciated. Thanks for the help in advance.
Edit: Formatted the code a bit and removed the NullPointerException as it was not happening anymore.
As stated in comments:
Me: In your first bit of code you have this try { List<Alert> alert.., but you do absolutely nothing with the newly declared alert List<Alert>. It this where the data is supposed to be coming from?
OP: I'm under the impression that that bit of code is the one that pushes the JSON Array to the Alert.class. Is there something I'm missing there?
Me: And what makes you think it does that? All it does is read the json, and the Alert.class argument is the class type argument, so the mapper know the results should be mapped to the Alert attributes when it creates the Alert objects. That's how doing List<Alert> is possible, because passing Alert.class decribes T in List<T>. The List<Alert> is what's returned from the reading, but you have to determine what to actually do with the list. And currently, you do absolutely nothing with it
You maybe want to change the class just a bit.
Now this is in no way a good design, just an example of how you can get it to work. I would take some time to sit and think about how you want the restConnector to be fully utilized
That being said, you can have a List<Alert> alerts; class member in the restConnector class. And have a getter for it
public class restConnector {
private List<Alert> alerts;
public List<Alert> getAlerts() {
return alerts;
}
...
}
Then when deserializing with the mapper, assign the value to private List<Alert> alerts. What you are doing is declaring a new locally scoped list. So instead of
try {
List<Alert> alert = mapper.readValue...
do this instead
try {
alerts = mapper.readValue
Now the class member is assigned a value. So in the Application class you can do something like
public class Application {
List<Alert> alerts;
restConnector connect;
public Application() {
initComponents();
}
private void initComponents() {
connector = restConnector.getInstance();
connector.init();
alerts = connector.getAlerts();
refreshData();
}
private void refreshData() {
StringBuilder sb = new StringBuilder();
for (Alert alert : alerts) {
sb.append(alert.toString()).append("\n");
}
System.out.println("appalertList: "+ sb.toString());
}
}
Now you have access to the Alerts in the list.
But let me reiterate: THIS IS A HORRIBLE DESIGN. For one you are limiting the init method to one single call, in which it is only able to obtain one and only one resource. What if the rest service needs to access a different resource? You have made the request set in stone, so you cant.
Take some time to think of some good OOP designs where the class can be used for different scenarios.