Passing a method data to other method in same Activity - json

I am newbie to Android Studio and I am making my final year project.
I made a QR code scanner that can retrieve data from HTTP using Rest API.
My question is: I need to send all the JSON data to other activity, based on my research I need to put intent on my button, because of that I need to pass my JsonRequest data to Btn_BuyClicked method so I can send all those to next activity.
I used AndroidHive MovieTickets so Im not changing so much coding.
Please help me. Thank you.
public class TicketResultActivity extends AppCompatActivity {
private static final String TAG = TicketResultActivity.class.getSimpleName();
private Button btnBuy;
private ImageView imgPoster;
private ProgressBar progressBar;
private TicketView ticketView;
private TextView txtDirector;
private TextView txtYear_created;
private TextView txtError;
private TextView txtType_powder;
private TextView txtApa_number;
private TextView txtLocation;
private TextView txtDate_expired;
private Button signOut;
private FirebaseAuth auth;
private class Movie {
String director;
String year_created;
String type_powder;
#SerializedName("released")
boolean isReleased;
String apa_number;
String poster;
String location;
String date_expired;
private Movie() {
}
public String getApa_number() {
return this.apa_number;
}
public String getDirector() {
return this.director;
}
public String getPoster() {
return this.poster;
}
public String getYear_created() {
return this.year_created;
}
public String getType_powder() {
return this.type_powder;
}
public String getLocation() {
return this.location;
}
public String getDate_expired() {
return this.date_expired;
}
public boolean isReleased() {
return this.isReleased;
}
}
NotificationCompat.Builder notification;
private static final int uniqueID = 250298;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ticket_result);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.txtApa_number = (TextView) findViewById(R.id.apa_number);
this.txtDirector = (TextView) findViewById(R.id.director);
this.txtYear_created = (TextView) findViewById(R.id.year_created);
this.txtLocation = (TextView) findViewById(R.id.location);
this.txtDate_expired = (TextView) findViewById(R.id.date_expired);
this.imgPoster = (ImageView) findViewById(R.id.poster);
this.txtType_powder = (TextView) findViewById(R.id.type_powder);
this.btnBuy = (Button) findViewById(R.id.btn_buy);
this.imgPoster = (ImageView) findViewById(R.id.poster);
this.txtError = (TextView) findViewById(R.id.txt_error);
this.ticketView = (TicketView) findViewById(R.id.layout_ticket);
this.progressBar = (ProgressBar) findViewById(R.id.progressBar);
String barcode = getIntent().getStringExtra("code");
if (TextUtils.isEmpty(barcode)) {
Toast.makeText(getApplicationContext(), "Barcode is empty!", Toast.LENGTH_LONG).show();
finish();
}
searchBarcode(barcode);
}
public void btn_buyClicked(View view) {
notification.setSmallIcon(R.drawable.qrcode);
notification.setTicker("This is the ticker");
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("Fire Extinguisher Scanner");
Intent intent = new Intent(this, Test.class);
startActivity(new Intent(TicketResultActivity.this, Test.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(uniqueID, notification.build());
}
private void searchBarcode(String barcode) {
MyApplication.getInstance().addToRequestQueue(new JsonObjectRequest(Request.Method.GET, barcode, null, new Listener<JSONObject>() {
public void onResponse(JSONObject response) {
Log.e(TicketResultActivity.TAG, "Ticket response: " + response.toString());
if (response.has("error")) {
TicketResultActivity.this.showNoTicket();
} else {
TicketResultActivity.this.renderMovie(response);
}
}
}, new ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TicketResultActivity.TAG, "Error: " + error.getMessage());
TicketResultActivity.this.showNoTicket();
}
}));
}
private void showNoTicket() {
this.txtError.setVisibility(View.VISIBLE);
this.ticketView.setVisibility(View.GONE);
this.progressBar.setVisibility(View.GONE);
}
public void renderMovie(JSONObject response) {
try {
Movie movie = (Movie) new Gson().fromJson(response.toString(), Movie.class);
if (movie != null) {
this.txtApa_number.setText(movie.getApa_number());
this.txtDirector.setText(movie.getDirector());
this.txtYear_created.setText(movie.getYear_created());
this.txtType_powder.setText(movie.getType_powder());
this.txtDate_expired.setText(BuildConfig.FLAVOR + movie.getDate_expired());
this.txtLocation.setText(movie.getLocation());
Glide.with(this).load(movie.getPoster()).into(this.imgPoster);
notification.setContentText("Fire Extinguisher "+ movie.getApa_number()+"successfully remind!");
if (movie.isReleased()) {
this.btnBuy.setText(getString(R.string.btn_buy_now));
this.btnBuy.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
} else {
this.btnBuy.setText(getString(R.string.btn_buy_now));
this.btnBuy.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
}
this.ticketView.setVisibility(View.VISIBLE);
this.progressBar.setVisibility(View.GONE);
return;
}
showNoTicket();
} catch (JsonSyntaxException e) {
Log.e(TAG, "JSON Exception: " + e.getMessage());
showNoTicket();
Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show();
} catch (Exception e2) {
showNoTicket();
Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show();
}
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
}
This is my TicketResultActivity.java class UPDATED CODE
private static class Movie implements Parcelable {
String director;
String year_created;
String type_powder;
#SerializedName("released")
boolean isReleased;
String apa_number;
String poster;
String location;
String date_expired;
public Movie() {
}
public Movie(Parcel in) {
director = in.readString();
year_created = in.readString();
type_powder = in.readString();
isReleased = in.readByte() != 0;
apa_number = in.readString();
poster = in.readString();
location = in.readString();
date_expired = in.readString();
}
public String getApa_number(){
return this.apa_number;
}
public String getYear_created() {
return year_created;
}
public String getType_powder() {
return type_powder;
}
public String getDirector() {
return director;
}
public String getPoster() {
return poster;
}
public String getLocation() {
return location;
}
public boolean isReleased() {
return isReleased;
}
public String getDate_expired() {
return date_expired;
}
public void setApa_number(String apa_number){
this.apa_number = apa_number;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(director);
dest.writeString(year_created);
dest.writeString(type_powder);
dest.writeByte((byte) (isReleased ? 1 : 0));
dest.writeString(apa_number);
dest.writeString(poster);
dest.writeString(location);
dest.writeString(date_expired);
}
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>() {
#Override
public Movie createFromParcel(Parcel in) {
return new Movie(in);
}
#Override
public Movie[] newArray(int size) {
return new Movie[size];
}
};
#Override
public int describeContents() {
return 0;
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ticket_result);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.txtApa_number = (TextView) findViewById(R.id.apa_number);
this.txtDirector = (TextView) findViewById(R.id.director);
this.txtYear_created = (TextView) findViewById(R.id.year_created);
this.txtLocation = (TextView) findViewById(R.id.location);
this.txtDate_expired = (TextView) findViewById(R.id.date_expired);
this.imgPoster = (ImageView) findViewById(R.id.poster);
this.txtType_powder = (TextView) findViewById(R.id.type_powder);
this.btnBuy = (Button) findViewById(R.id.btn_buy);
this.imgPoster = (ImageView) findViewById(R.id.poster);
this.txtError = (TextView) findViewById(R.id.txt_error);
this.ticketView = (TicketView) findViewById(R.id.layout_ticket);
this.progressBar = (ProgressBar) findViewById(R.id.progressBar);
String barcode = getIntent().getStringExtra("code");
if (TextUtils.isEmpty(barcode)) {
Toast.makeText(getApplicationContext(), "Barcode is empty!", Toast.LENGTH_LONG).show();
finish();
}
searchBarcode(barcode);
}
public void btn_buyClicked(View view) {
// In activity or fragment
Movie movie = new Movie();
movie.setApa_number("xyz");
Intent intent = new Intent(this, Test.class);
intent.putExtra("parcel_data", movie);
startActivity(intent);
}
private void searchBarcode(String barcode) {
MyApplication.getInstance().addToRequestQueue(new JsonObjectRequest(Request.Method.GET, barcode, null, new Listener<JSONObject>() {
public void onResponse(JSONObject response) {
Log.e(TicketResultActivity.TAG, "Ticket response: " + response.toString());
if (response.has("error")) {
TicketResultActivity.this.showNoTicket();
} else {
TicketResultActivity.this.renderMovie(response);
}
}
}, new ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TicketResultActivity.TAG, "Error: " + error.getMessage());
TicketResultActivity.this.showNoTicket();
}
}));
}
private void showNoTicket() {
this.txtError.setVisibility(View.VISIBLE);
this.ticketView.setVisibility(View.GONE);
this.progressBar.setVisibility(View.GONE);
}
public void renderMovie(JSONObject response) {
try {
Movie movie = (Movie) new Gson().fromJson(response.toString(), Movie.class);
if (movie != null) {
this.txtApa_number.setText(movie.getApa_number());
this.txtDirector.setText(movie.getDirector());
this.txtYear_created.setText(movie.getYear_created());
this.txtType_powder.setText(movie.getType_powder());
this.txtDate_expired.setText(BuildConfig.FLAVOR + movie.getDate_expired());
this.txtLocation.setText(movie.getLocation());
Glide.with(this).load(movie.getPoster()).into(this.imgPoster);
if (movie.isReleased()) {
this.btnBuy.setText(getString(R.string.btn_buy_now));
this.btnBuy.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
} else {
this.btnBuy.setText(getString(R.string.btn_buy_now));
this.btnBuy.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
}
this.ticketView.setVisibility(View.VISIBLE);
this.progressBar.setVisibility(View.GONE);
return;
}
showNoTicket();
} catch (JsonSyntaxException e) {
Log.e(TAG, "JSON Exception: " + e.getMessage());
showNoTicket();
Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show();
} catch (Exception e2) {
showNoTicket();
Toast.makeText(getApplicationContext(), "Error occurred. Check your LogCat for full report", Toast.LENGTH_SHORT).show();
}
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
}
This is Test.java Class
public class Test extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Movie movie = (Movie) getIntent().getParcelableExtra("parcel_data");
String apa_number = movie.getApa_number();
TextView textView1 = findViewById(R.id.textView2);
textView1.setText(apa_number);
}
}

Use Parcelable is an interface. A class who implements Parcelable can write to and read from a Parcel.
You need to follow 3 points to create a Parcelable class.
A Class must implement Parcelable interface
A Class must have a non-null static field CREATOR of a type that implements Parcelable.Creator interface.
Override writeToParcel method and write member variable in Parcel. Make sure to read variables in the same sequence in which they are written in Parcel. Order of read and write matters.
private class Movie implements Parcelable{
String director;
String year_created;
String type_powder;
#SerializedName("released")
boolean isReleased;
String apa_number;
String poster;
String location;
String date_expired;
public Movie() {
}
// In constructor you will read the variables from Parcel. Make sure to read them in the same sequence in which you have written them in Parcel.
public Movie(Parcel in) {
director = in.readString();
year_created = in.readString();
release_date = in.readString();
poster = in.readString();
}
public String getApa_number() {
return this.apa_number;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
// This is where you will write your member variables in Parcel. Here you can write in any order. It is not necessary to write all members in Parcel.
#Override
public void writeToParcel(Parcel dest, int flags) {
// Write data in any order
dest.writeString(director);
dest.writeString(year_created);
dest.writeString(release_date);
dest.writeString(poster);
}
// This is to de-serialize the object
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>(){
public Movie createFromParcel(Parcel in) {
return new Movie(in);
}
public Movie[] newArray(int size) {
return new Movie[size];
}
};
}
Now you can pass a Parcelable object using Intent.
// In activity or fragment
Movie movie = new Movie();
movie.setDirector("xyz");
// now you can set all values like :year created, is released whatever.
// using context and next component class to create intent
Intent intent = new Intent(this, NextActivity.class);
// using putExtra(String key, Parcelable value) method
intent.putExtra(“parcel_data”, movie);
startActivity(intent);
You can access this data in NextActivity –
public class NextActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Using getParcelableExtra(String key) method
Movie movie = (Movie) getIntent().getParcelableExtra("parcel_data");
String director = movie.getDirector();
}
}

There are so many ways to send data from one activity to another activity. If you Have Primitive or Json string type data then you can directly put that data into the intent.
But if in case you have Model class and you need to pass it. Then you have two ways:
Serializable
Parcelable
But Android recommend to use Parcelable.
You can also add plugin to android studio to generate the parcelable code.

Related

get the data in recyclerview

Hello everyone i am getting the messages of the users in android studio for that i am refreshing the recyclerview every second but the probem is scrolling when i am scrooling the recyclerview to old messages then its not scrooling becouse of the getting data every second can someone please help me in this
bellow is my activity code
public class Message_User_Activity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_user);
content();
Clicks();
}
public void content()
{
getdata();
refresh(100);
}
private void refresh(int milliseconds)
{
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
content();
}
};
handler.postDelayed(runnable,milliseconds);
}
private void getdata()
{
toolbar_user_name.setText(name);
String Choice = "Get Messages";
Call<List<responsemodel>> call = SplashScreen.apiInterface.getfullprofiledata(Choice,Message_To,Message_From);
call.enqueue(new Callback<List<responsemodel>>() {
#Override
public void onResponse(Call<List<responsemodel>> call, Response<List<responsemodel>> response) {
List<responsemodel> data = response.body();
Message_user_Adapter adapter = new Message_user_Adapter(data,Message_To);
messages_Message_user_RecyclerView.setAdapter(adapter);
messages_Message_user_RecyclerView.scrollToPosition(messages_Message_user_RecyclerView.getAdapter().getItemCount() -1);
}
#Override
public void onFailure(Call<List<responsemodel>> call, Throwable t) {
}
});
}
}
below is my adapter code
public class Message_user_Adapter extends RecyclerView.Adapter<Message_user_Adapter.Message_user_Adapter_View_Holder>
{
List<responsemodel> data;
String mmessage_To;
public Message_user_Adapter(List<responsemodel> data, String message_To) {
this.data = data;
this.mmessage_To = message_To;
}
#NonNull
#Override
public Message_user_Adapter_View_Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_messages_layout,parent,false);
return new Message_user_Adapter_View_Holder(view);
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onBindViewHolder(#NonNull Message_user_Adapter_View_Holder holder, int position) {
String time = calculateTime(data.get(position).getMessage_Time());
if (data.get(position).getMessage_From().equals(mmessage_To))
{
holder.other_user_message_message_layout.setVisibility(View.VISIBLE);
holder.other_user_message_message_layout.setText(data.get(position).getMessage() + "\n \n" + time);
holder.message_message_layout.setVisibility(View.GONE);
}
else
{
holder.other_user_message_message_layout.setVisibility(View.GONE);
holder.message_message_layout.setText(data.get(position).getMessage() + "\n \n" + time);
holder.message_message_layout.setVisibility(View.VISIBLE);
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
private String calculateTime(String post_time)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
long time = sdf.parse(post_time).getTime();
long now = System.currentTimeMillis();
CharSequence ago =
DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
return ago+"";
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
#Override
public int getItemCount() {
return data.size();
}
public String getdata() {
return mmessage_To.toString();
}
class Message_user_Adapter_View_Holder extends RecyclerView.ViewHolder
{
TextView other_user_message_message_layout;
TextView message_message_layout;
CircleImageView toolbar_user_profile;
public Message_user_Adapter_View_Holder(#NonNull View itemView) {
super(itemView);
other_user_message_message_layout = itemView.findViewById(R.id.other_user_message_message_layout);
message_message_layout = itemView.findViewById(R.id.message_message_layout);
}
}
}
According to my simple information
in your getdata() function. you send new data to Message_user_Adapter of RecyclerView every time you receive data from API or whatever you use ,so the data of adapter every second is change to new data ,so the RecyclerView being recreated every second with new data and the scroll will not work
just try to outage this lines from onResponse to the first of getdata():
Message_user_Adapter adapter = new Message_user_Adapter(data,Message_To);
messages_Message_user_RecyclerView.setAdapter(adapter);
and in its place add this line to notify the adapter about changed data :
adapter.notifyDatasetChanged()
something like this :
private void getdata() {
toolbar_user_name.setText(name);
String Choice = "Get Messages";
List<responsemodel> data = new ArrayList<>();//this line was change
Message_user_Adapter adapter = new Message_user_Adapter(data,Message_To);//this line was change
messages_Message_user_RecyclerView.setAdapter(adapter);//this line was change
Call<List<responsemodel>> call = SplashScreen.apiInterface.getfullprofiledata(Choice,Message_To,Message_From);
call.enqueue(new Callback<List<responsemodel>>() {
#Override
public void onResponse(Call<List<responsemodel>> call, Response<List<responsemodel>> response) {
data = response.body();
adapter.notifyDatasetChanged()//this line was added
messages_Message_user_RecyclerView.scrollToPosition(messages_Message_user_RecyclerView.getAdapter().getItemCount() -1);
}
#Override
public void onFailure(Call<List<responsemodel>> call, Throwable t) {
}
});
}

D/Volley: [1] 5.onErrorResponse: Product

How do I insert data from MySQL into Gridview on Fragments? I've tried it with a coding method used for Activity. I've changed a lot but it's still wrong. This is my coding:
/**
* A simple {#link Fragment} subclass.
*/
public class Product extends Fragment implements
SwipeRefreshLayout.OnRefreshListener {
GridView grid_product;
SwipeRefreshLayout swipe;
List<ProductData> newsList = new ArrayList<ProductData>();
private static final String TAG = Product.class.getSimpleName();
private static String url_list = Server.URL + "news.php?offset=";
private int offSet = 0;
int no;
ProductAdapter adapter;
public static final String TAG_NO = "no";
public static final String TAG_ID = "id";
public static final String TAG_JUDUL = "judul";
public static final String TAG_TGL = "tgl";
public static final String TAG_ISI = "isi";
public static final String TAG_GAMBAR = "gambar";
Handler handler;
Runnable runnable;
public Product() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_product, container, false);
swipe = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
grid_product = (GridView) view.findViewById(R.id.grid_product);
setProduct();
return view;
}
private void setProduct(){
adapter = new ProductAdapter(getActivity(), newsList);
grid_product.setAdapter(adapter);
grid_product.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//pindah activity
startActivity(new Intent(
getActivity(), DetailActivity.class
));
}
});
I don't know where the mistake is:
swipe.setOnRefreshListener(this);
swipe.post(new Runnable() {
#Override
public void run() {
swipe.setRefreshing(true);
newsList.clear();
adapter.notifyDataSetChanged();
callNews(0);
}
}
);
grid_product.setOnScrollListener(new AbsListView.OnScrollListener() {
private int currentVisibleItemCount;
private int currentScrollState;
private int currentFirstVisibleItem;
private int totalItem;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItem = totalItemCount;
}
private void isScrollCompleted() {
if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
&& this.currentScrollState == SCROLL_STATE_IDLE) {
swipe.setRefreshing(true);
handler = new Handler();
runnable = new Runnable() {
public void run() {
callNews(offSet);
}
};
handler.postDelayed(runnable, 3000);
}
}
});
}
#Override
public void onRefresh() {
newsList.clear();
adapter.notifyDataSetChanged();
callNews(0);
}
I don't know where the mistake is:
private void callNews(int page){
swipe.setRefreshing(true);
// Creating volley request obj
JsonArrayRequest arrReq = new JsonArrayRequest(url_list + page,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
if (response.length() > 0) {
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
ProductData news = new ProductData();
no = obj.getInt(TAG_NO);
news.addId(obj.getString(TAG_ID));
news.addJudul(obj.getString(TAG_JUDUL));
if (obj.getString(TAG_GAMBAR) != "") {
news.addGambar(obj.getString(TAG_GAMBAR));
}
news.addDatetime(obj.getString(TAG_TGL));
news.addIsi(obj.getString(TAG_ISI));
// adding news to news array
newsList.add(news);
if (no > offSet)
offSet = no;
Log.d(TAG, "offSet " + offSet);
} catch (JSONException e) {
Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}
swipe.setRefreshing(false);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
swipe.setRefreshing(false);
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(arrReq);
}
}

Jackson JSON Can not construct instance of "About" : deserialize issue

I've make HttpsURLConnection to receive some information about my server.
The result of response is :
{"about":{"title":"NiFi","version":"1.1.0","uri":"https://localhost:443/api/","contentViewerUrl":"/nifi-content-viewer/","timezone":"CET"}}
How is possible to extract all attributes and key/value ?
About.class file
public class About {
private List<AboutObject> about;
public About()
{
// this.about = about;
}
public List<AboutObject> getAbout() {
return this.about;
}
public void setAbout(List<AboutObject> about) {
this.about = about;
}
}
AboutObject.class
public class AboutObject {
private String title;
private String uri;
private String contentViewerUrl;
private String timezone;
public String getTitle()
{
return this.title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getUri()
{
return this.uri;
}
public void setUri(String uri)
{
this.uri = uri;
}
public String getContentViewerUrl()
{
return this.contentViewerUrl;
}
public void setContentViewerUrl(String contentViewerUrl)
{
this.contentViewerUrl = contentViewerUrl;
}
public String getTimeZone()
{
return this.timezone;
}
public void setTimeZone(String timezone)
{
this.timezone = timezone;
}
}
Main.class
HttpsURLConnection con = (HttpsURLConnection) 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("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + 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();
//print result
System.out.println(response.toString());
System.out.println("Contenu de in = " + in.toString());
ObjectMapper mapper = new ObjectMapper();
//Staff objStaff = new Staff();
System.out.println("Object to JSON in file");
mapper.writeValue(new File("output/file.json"), response);
System.out.println("Convert JSON string from file to Object");
//String about = mapper.readValue(new File("output/file.json"), String.class);
About about = mapper.readValue(new File("output/file.json"), About.class);
Error
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of About: no String-argument constructor/factory method to deserialize from String value ('{"about":{"title":"NiFi","version":"1.1.0","uri":"https://localhost:443/api/","contentViewerUrl":"/nifi-content-viewer/","timezone":"CET"}}') at [Source: output/file.json; line: 1, column: 1]
Thanks for you help
The test json you show doesn't have the array wrapper used in your About object. You're also missing the version field in your AboutObject and the timezone field uses the wrong case.
Your example worked when I updated your objects:
public class About {
private AboutObject about;
public AboutObject getAbout() {
return about;
}
public void setAbout(AboutObject about) {
this.about = about;
}
}
public class AboutObject {
private String title;
private String uri;
private String contentViewerUrl;
private String timezone;
private String version;
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUri() {
return this.uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getContentViewerUrl() {
return this.contentViewerUrl;
}
public void setContentViewerUrl(String contentViewerUrl) {
this.contentViewerUrl = contentViewerUrl;
}
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
Test:
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String obj = "{\"about\":{\"title\":\"NiFi\",\"version\":\"1.1.0\",\"uri\":\"https://localhost:443/api/\",\"contentViewerUrl\":\"/nifi-content-viewer/\",\"timezone\":\"CET\"}}";
About about = mapper.readValue(obj, About.class);
}

How to send a JSON object to a server with Volley library in android?

I want to send a json object to the server using the post method.
I have used volley library to pass the string params, and it's working fine, but when I run my app I am getting this:
BasicNetwork.performRequest: Unexpected response code 400
my code:-
public class MainActivity extends AppCompatActivity {
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
makeJsonObjReq();
}
private void makeJsonObjReq() {
JSONObject request=new JSONObject();
try {
request.put("ProductCode", "KK03672-038");
} catch (JSONException e) {
e.printStackTrace();
}
pd = ProgressDialog.show(MainActivity.this, "Alert", "Please Wait...");
JsonObjectRequest jsonObjReq = new JsonObjectRequest(
"URL",request,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
pd.dismiss();
System.out.println("Response is====>" + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.dismiss();
System.out.println("Error is====>" + error.getMessage());
}
}) {
/**
* Passing some request headers
* */
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
// Adding request to request queue:-
AppController.getInstance().addToRequestQueue(jsonObjReq);
}
}
AppContoller:-
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache());
}
return this.mImageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Try adding volley initialization code in Application class and reference this to your manifest application tag.

org.codehaus.jackson.JsonGenerationException: Can not write number, expecting field name

Hi i am working on a spring mvc application well i need to Serialize an object in order to pass it with an ajax Post.
my bean class :
#JsonSerialize(using = AgentSer.class)
public class AgentCust implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long personneID;
private String nom;
private String prenom;
private String matriculation;
private String marche;
private String compte;
private String phone, mail, chat;
public String getMarche() {
return marche;
}
public void setMarche(String marche) {
this.marche = marche;
}
public String getCompte() {
return compte;
}
public void setCompte(String compte) {
this.compte = compte;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getChat() {
return chat;
}
public void setChat(String chat) {
this.chat = chat;
}
public Long getPersonneID() {
return personneID;
}
public void setPersonneID(Long personneID) {
this.personneID = personneID;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getMatriculation() {
return matriculation;
}
public void setMatriculation(String matriculation) {
this.matriculation = matriculation;
}
}
and the class that will serialize my bean :
public class AgentSer extends JsonSerializer<AgentCust> {
#Override
public void serialize(AgentCust value, JsonGenerator jgen, SerializerProvider arg2) throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
jgen.writeStartObject();
jgen.writeNumber(value.getPersonneID());
jgen.writeString(value.getMatriculation());
jgen.writeString(value.getNom());
jgen.writeString(value.getPrenom());
jgen.writeString(value.getCompte());
jgen.writeString(value.getMarche());
jgen.writeString(value.getChat());
jgen.writeString(value.getMail());
jgen.writeString(value.getPhone());
jgen.writeEndObject();
}
}
in my controller i use my class like that:
AgentCust ags ;
// i set values here .
ObjectMapper mapper = new ObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(ags);
} catch (Exception e) {
System.out.println(e);
}
but at the end i get that :
org.codehaus.jackson.JsonGenerationException: Can not write number, expecting field name
any help please.
Why are you using a custom serializer(which is wrong as it doesn't include the field names). You are really complicating your life.
You can set the serialization options like this (you can also set them in a static block):
final ObjectMapper mapper = new ObjectMapper();
/*
you can set them globally in a static block and reuse the mapper...
performance gain
*/
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
mapper.setSerializationInclusion(Include.NON_NULL);
The rest of the code is the same(just add a constructor in your AgentCust.class to avoid some mapping errors):
AgentCust ags = new AgentCust();
ags.setChat("chat1");
ags.setCompte("compte1");
ags.setMail("mail1");
ags.setMarche("marche1");
ags.setMatriculation("matriculation1");
ags.setNom("nom1");
ags.setPersonneID(123456L);
ags.setPhone("phone1");
ags.setPrenom("prenom1");
String json = "";
try {
json = mapper.writeValueAsString(ags);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(json);
Another strange thing is that you're serializing the pojo as String. Why not JsonNode or ObjectNode?
public static ObjectNode convObjToONode(Object o) {
StringWriter stringify = new StringWriter();
ObjectNode objToONode = null;
try {
mapper.writeValue(stringify, o);
objToONode = (ObjectNode) mapper.readTree(stringify.toString());
} catch (JsonMappingException e) {
Logger.error("ERROR MAPPING JSON from object!", e);
} catch (JsonGenerationException e) {
Logger.error("ERROR GENERATING JSON from object!", e);
} catch (IOException e) {
Logger.error("ERROR IO when writing JSON from object!", e);
}
Logger.debug("Object as ObjectNode : " + objToONode);
return objToONode;
}