Refresh Json in Fragment1 each 60s and update the data in Fragment2 - json

Hi everybody!!
I have two fragments:Fragment1 and Fragment2; Fragment1 contains Json,and after getting Json, I replace Fragment1 to Fragment2 via .replace(..) and transfer the Json via Bundle.
My Goal is: Refresh Json in Fragment1 each 60s for example and update automatically Fragment2 but i don't know how to do that!! i need your help!!
this is my code:
Class Fragment1
public class Fragment1 extends Fragment implements OnClickListener{
public static final String IMAGE_RESOURCE_ID="iconResourceID";
public static final String ITEM_NAME="itemName";
Button btnvalider;
//test transfer variable entre fragment
public Communicator com;
public void setCom(Communicator com) {
this.com = com;
}
/*
* Test Jsonparser
*
*/
Context c;
private ProgressDialog pDialog;
public String testfinalewa="";
JSonParser jsonParser = new JSonParser();
// url to create new product
private static String url_create_product = "http://10.0.2.2/webservice/create_personne.php";
public String getTestfinalewa() {
return testfinalewa;
}
public void setTestfinalewa(String testfinalewa) {
this.testfinalewa = testfinalewa;
}
// JSON Node names
private static final String TAG_SUCCESS = "success";
//fin test json
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
c=getActivity();
return inflater.inflate(R.layout.fragment_1, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
btnvalider=(Button)getActivity().findViewById(R.id.button1);
btnvalider.setOnClickListener(this);
this.com=(Communicator) getActivity();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
public void run() {
// call JSON methods here
new AttemptLogin().execute();
}
}, 1 );
}
//interface pour transferer variable entre fragment
public interface Communicator{
public void respond(String data);
}
class AttemptLogin extends AsyncTask<String, String, String>{//<params,progress,result>
boolean failure = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(c);
pDialog.setMessage("Chargement...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String name ="test";// pseudo.getText().toString();
String moddepasse = "test";//mdp.getText().toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", name));
Log.i("misy ve", "ok="+moddepasse);
Log.i("misy ve", "ok="+name);
params.add(new BasicNameValuePair("moddepasse", moddepasse));
Log.i("test", "mbola tena mety eto 1");
// getting JSON Object
JSONObject json = jsonParser.makeHttpRequest(url_create_product,
"POST", params);
Log.d("Create Response", json.toString());
Log.i("test", "mbola tena mety eto");
try {
int success = json.getInt(TAG_SUCCESS);
String succ=json.getString("ok");
Log.i("milay", succ);
if ((success == 1)) {
Log.i("accepter", "mdp correct");
} else {
Log.i("pas accepter", "non correct");
}
} catch (JSONException e) {
e.printStackTrace();
}
return json.toString();
}
protected void onPostExecute(String result) {
pDialog.dismiss();
com.respond(result);
Fragment2 fb=new Fragment2();
FragmentTransaction t=getFragmentManager().beginTransaction();
Bundle args=new Bundle();
args.putString("mondata", result);
fb.setArguments(args);
t.replace(R.id.myFramePrincipal, fb).commit();
}
}
}
class Fragment2
public class Fragment2 extends Fragment{
TextView text;
String aa;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
text=(TextView) getActivity().findViewById(R.id.textView1);
text.setText(getArguments().getString("mondata"));
}
public void refreshData(String data) {
aa= new String(data);
//aa.notifyDataSetChanged();
text.setText(aa);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_3, container, false);
}
public void ChangerText(String data) {
text.setText(data);
}
}
Thanks for your help!!

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) {
}
});
}

Getting data in recyclerView

i am getting messages from the database into a recycler view but i want to refresh the recycler view every second for to adding different for to getting new messages in recycler view
But i haver an error of getting data please see it https://www.filemail.com/d/izhittgyibvcjxx
my code is
boolean refresh;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message_user);
refresh = true;
content();
}
public void content()
{
getdata();
if (refresh)
{
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()
{
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.smoothScrollToPosition(messages_Message_user_RecyclerView.getAdapter().getItemCount());
}
#Override
public void onFailure(Call<List<responsemodel>> call, Throwable t) {
}
});
}

notifyDataSetChanged on RecyclerView

I have a recyclerView and customAdaprer. I pass an list of an object (earthquakeList)to recycleradapter and then i do setAdapter:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
earthquakeList = new ArrayList<>();
adapter = new RecyclerViewAdapter(earthquakeList);
recyclerView.setAdapter(adapter);
}
I create AsyncTask on onResume method:
#Override
protected void onResume() {
super.onResume();
// Kick off an {#link AsyncTask} to perform the network request
new EarthQuakeAsyncTask().execute();
}
in AsyncTask my class i get a new List from my object that i get from internet and when I replaced this new list with older list and call notifyDataSetChanged, recyclerView still nothing show??
I debug my app and I get object from net.
I do in this way on list view but recylerview seems efferent.
I replace old list with the new list one like blow:
private class EarthQuakeAsyncTask extends AsyncTask<Void, Void, List<Earthquake>> {
#Override
protected List<Earthquake> doInBackground(Void... urls) {
// Create URL object
URL url = HttpRequest.createUrl(USGS_REQUEST_URL);
// perform HTTP request to the URL and receive a JSON response back
String jsonResponse = "";
try {
jsonResponse = HttpRequest.makeHttpRequest(url);
} catch (IOException e) {
e.printStackTrace();
}
List<Earthquake> earthquakes = HttpRequest.extractFeaturesFromJson(jsonResponse);
return earthquakes;
}
#Override
protected void onPostExecute(List<Earthquake> earthquakeList) {
super.onPostExecute(earthquakeList);
MainActivity.this.earthquakeList.clear();
MainActivity.this.earthquakeList.addAll(earthquakeList);
adapter.notifyDataSetChanged();
}
what is exactly my wrong?
************************ EDIT ********************
this is Adapter :
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyHolder> {
List<Earthquake> earthquakes;
public RecyclerViewAdapter(List<Earthquake> earthquakes) {
this.earthquakes = earthquakes;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.earthquak_list_item, parent, false);
MyHolder myHolder = new MyHolder(view);
return myHolder;
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
Earthquake earthquake = earthquakes.get(position);
holder.magnitude.setText(earthquake.getmMagnitude());
holder.location.setText(earthquake.getmLocation());
holder.time.setText(earthquake.getmDate());
}
#Override
public int getItemCount() {
return (null != earthquakes ? earthquakes.size() : 0);
}
public void setItems(List<Earthquake> earthquakeList) {
this.earthquakes = earthquakeList;
}
public class MyHolder extends RecyclerView.ViewHolder {
#BindView(R.id.magnitude)
TextView magnitude;
#BindView(R.id.location)
TextView location;
#BindView(R.id.date)
TextView time;
public MyHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
Ops ,I forgot put LayoutManager for recyclerView .
this is right code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
earthquakeList = new ArrayList<>();
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerViewAdapter(earthquakeList);
recyclerView.setAdapter(adapter);
}

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.

Spring REST service: retrieving JSON from Request

I am building a REST service on Spring 3.1. I am using #EnableWebMVC annotation for that. Since my service will only be accepting JSON requests, I would also like to dump the incoming request into a MongoDB collection for logging (and, later, for data transformation). I would like to access the raw JSON Request (which I could do on a non-spring implementation using "#Content HttpServletRequest request" as a method parameter).
I am a Spring newbie. So, kindly help me with directions to achieve this. Thanks!
UPDATE: The issue is not completely resolved. Only my tests with GET worked. It fails with POST. Therefore unchecked the accepted answer
The issue is, even if I create a HttpServletRequestWrapper, I cannot forward the request after I process and wrap the request. Here is what happens:
Interceptor:
public class DBLogInterceptor extends HandlerInterceptorAdapter {
MyRequestWrapper requestWrapper;
private final static Logger logger = Logger.getLogger(DBLogInterceptor.class);
#Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception
{
requestWrapper = new MyRequestWrapper(request);
// Code removed, but it just dumps requestWrapper.getBody() into DB
return super.preHandle(requestWrapper, response, handler);
}
}
HTTP POST Servicing method
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
#ResponseBody
public String updateEntity(#RequestBody Employee emp) {
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
Now I get an exception whenever I send a POST:
12:04:53,821 DEBUG DBLogInterceptor:22 - {"name":"Van Damme","dept":"Applied Martial Arts"}
12:04:53,843 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.test.webapp.login.domain.Employee] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter#154174f9]
12:04:53,850 DEBUG ExceptionHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Stream closed
12:04:53,854 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,854 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,859 DEBUG DispatcherServlet:910 - Could not complete request
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129)
at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224)
at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785)
at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1914)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I expected the HttpServletRequestWrapper to be taking care of caching the request. But it doesn't happen somehow.
Using the HttpServletRequest object, you can get access to the URL the client used to make the request, the method used (GET, POST, PUT, etc), the query string, and headers.
Getting the RequestBody may be a bit trickier and may require using the HttpServletRequestWrapper object. Since the request body can only be read once, you'll need to extend the wrapper to access it so that your target controller can still access it later to deserialize your JSON into POJO objects.
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
To access the requests in a central location, you can use either a Filter or a Spring Interceptor. Both of these are invoked prior to the request being delegated to the controller, and both have access to the servlet.
Here is an actual Logging example using a Spring Interceptor:
package com.vaannila.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler. HandlerInterceptorAdapter;
public class LoggerInterceptor extends HandlerInterceptorAdapter {
static Logger logger = Logger.getLogger(LoggerInterceptor.class);
static {
BasicConfigurator.configure();
}
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
logger.info("Before handling the request");
return super.preHandle(request, response, handler);
}
#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("After handling the request");
super.postHandle(request, response, handler, modelAndView);
}
#Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info("After rendering the view");
super.afterCompletion(request, response, handler, ex);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<bean id="handlerMapping" class="org.springframework.web.servlet.handler. BeanNameUrlHandlerMapping" p:interceptors-ref="loggerInterceptor" />
<bean id="loggerInterceptor" class="com.vaannila.interceptor.LoggerInterceptor" />
<bean id="userService" class="com.vaannila.service.UserServiceImpl" />
<bean name="/userRegistration.htm" class="com.vaannila.web.UserController" p:userService-ref="userService" p:formView="userForm" p:successView="userSuccess" />
</beans>
In the LoggerInterceptor, you could use the following code to access the request:
MyRequestWrapper myRequestWrapper = new MyRequestWrapper((HttpServletRequest) request);
String body = myRequestWrapper.getBody();
String clientIP = myRequestWrapper.getRemoteHost();
int clientPort = request.getRemotePort();
String uri = myRequestWrapper.getRequestURI();
System.out.println(body);
System.out.println(clientIP);
System.out.println(clientPort);
System.out.println(uri);
I doubt if HttpServletRequestWrapper can ever work... Take a look at the DispatcherServlet implementation:
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;
}
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
It passes reference to "processedRequest" still, which refers to a HttpServletRequest request whose stream has already been read.
I know this is an old question, but for those of you that are still looking for a solution, this worked for me:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
Map<String, String> requestMap = this
.getTypesafeRequestMap(httpServletRequest);
BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
httpServletRequest);
BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
httpServletResponse);
final StringBuilder logMessage = new StringBuilder(
"REST Request - ").append("[HTTP METHOD:")
.append(httpServletRequest.getMethod())
.append("] [PATH INFO:")
.append(httpServletRequest.getPathInfo())
.append("] [REQUEST PARAMETERS:").append(requestMap)
.append("] [REQUEST BODY:")
.append(bufferedRequest.getRequestBody())
.append("] [REMOTE ADDRESS:")
.append(httpServletRequest.getRemoteAddr()).append("]");
chain.doFilter(bufferedRequest, bufferedResponse);
logMessage.append(" [RESPONSE:")
.append(bufferedResponse.getContent()).append("]");
logger.debug(logMessage.toString());
} catch (Throwable a) {
logger.error(a.getMessage());
}
}
private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
Map<String, String> typesafeRequestMap = new HashMap<String, String>();
Enumeration<?> requestParamNames = request.getParameterNames();
while (requestParamNames.hasMoreElements()) {
String requestParamName = (String) requestParamNames.nextElement();
String requestParamValue = request.getParameter(requestParamName);
typesafeRequestMap.put(requestParamName, requestParamValue);
}
return typesafeRequestMap;
}
#Override
public void destroy() {
}
private static final class BufferedRequestWrapper extends
HttpServletRequestWrapper {
private ByteArrayInputStream bais = null;
private ByteArrayOutputStream baos = null;
private BufferedServletInputStream bsis = null;
private byte[] buffer = null;
public BufferedRequestWrapper(HttpServletRequest req)
throws IOException {
super(req);
// Read InputStream and store its content in a buffer.
InputStream is = req.getInputStream();
this.baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int read;
while ((read = is.read(buf)) > 0) {
this.baos.write(buf, 0, read);
}
this.buffer = this.baos.toByteArray();
}
#Override
public ServletInputStream getInputStream() {
this.bais = new ByteArrayInputStream(this.buffer);
this.bsis = new BufferedServletInputStream(this.bais);
return this.bsis;
}
String getRequestBody() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
this.getInputStream()));
String line = null;
StringBuilder inputBuffer = new StringBuilder();
do {
line = reader.readLine();
if (null != line) {
inputBuffer.append(line.trim());
}
} while (line != null);
reader.close();
return inputBuffer.toString().trim();
}
}
private static final class BufferedServletInputStream extends
ServletInputStream {
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
#Override
public int available() {
return this.bais.available();
}
#Override
public int read() {
return this.bais.read();
}
#Override
public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
}
public class TeeServletOutputStream extends ServletOutputStream {
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two) {
targetStream = new TeeOutputStream(one, two);
}
#Override
public void write(int arg0) throws IOException {
this.targetStream.write(arg0);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
}
public class BufferedResponseWrapper implements HttpServletResponse {
HttpServletResponse original;
TeeServletOutputStream tee;
ByteArrayOutputStream bos;
public BufferedResponseWrapper(HttpServletResponse response) {
original = response;
}
public String getContent() {
return bos.toString();
}
public PrintWriter getWriter() throws IOException {
return original.getWriter();
}
public ServletOutputStream getOutputStream() throws IOException {
if (tee == null) {
bos = new ByteArrayOutputStream();
tee = new TeeServletOutputStream(original.getOutputStream(),
bos);
}
return tee;
}
#Override
public String getCharacterEncoding() {
return original.getCharacterEncoding();
}
#Override
public String getContentType() {
return original.getContentType();
}
#Override
public void setCharacterEncoding(String charset) {
original.setCharacterEncoding(charset);
}
#Override
public void setContentLength(int len) {
original.setContentLength(len);
}
#Override
public void setContentType(String type) {
original.setContentType(type);
}
#Override
public void setBufferSize(int size) {
original.setBufferSize(size);
}
#Override
public int getBufferSize() {
return original.getBufferSize();
}
#Override
public void flushBuffer() throws IOException {
tee.flush();
}
#Override
public void resetBuffer() {
original.resetBuffer();
}
#Override
public boolean isCommitted() {
return original.isCommitted();
}
#Override
public void reset() {
original.reset();
}
#Override
public void setLocale(Locale loc) {
original.setLocale(loc);
}
#Override
public Locale getLocale() {
return original.getLocale();
}
#Override
public void addCookie(Cookie cookie) {
original.addCookie(cookie);
}
#Override
public boolean containsHeader(String name) {
return original.containsHeader(name);
}
#Override
public String encodeURL(String url) {
return original.encodeURL(url);
}
#Override
public String encodeRedirectURL(String url) {
return original.encodeRedirectURL(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeUrl(String url) {
return original.encodeUrl(url);
}
#SuppressWarnings("deprecation")
#Override
public String encodeRedirectUrl(String url) {
return original.encodeRedirectUrl(url);
}
#Override
public void sendError(int sc, String msg) throws IOException {
original.sendError(sc, msg);
}
#Override
public void sendError(int sc) throws IOException {
original.sendError(sc);
}
#Override
public void sendRedirect(String location) throws IOException {
original.sendRedirect(location);
}
#Override
public void setDateHeader(String name, long date) {
original.setDateHeader(name, date);
}
#Override
public void addDateHeader(String name, long date) {
original.addDateHeader(name, date);
}
#Override
public void setHeader(String name, String value) {
original.setHeader(name, value);
}
#Override
public void addHeader(String name, String value) {
original.addHeader(name, value);
}
#Override
public void setIntHeader(String name, int value) {
original.setIntHeader(name, value);
}
#Override
public void addIntHeader(String name, int value) {
original.addIntHeader(name, value);
}
#Override
public void setStatus(int sc) {
original.setStatus(sc);
}
#SuppressWarnings("deprecation")
#Override
public void setStatus(int sc, String sm) {
original.setStatus(sc, sm);
}
#Override
public String getHeader(String arg0) {
return original.getHeader(arg0);
}
#Override
public Collection<String> getHeaderNames() {
return original.getHeaderNames();
}
#Override
public Collection<String> getHeaders(String arg0) {
return original.getHeaders(arg0);
}
#Override
public int getStatus() {
return original.getStatus();
}
}
}
Then simply register the filter in web.xml and you're done. All credits to: http://wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431 (I just did some minor fix to it).
Hey can you try with this:
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "/employee")
#ResponseBody
public String updateEntity(#RequestBody Employee emp) {
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
Here: it you proving URI with the '/' it allows all the operations to perform. such as get post update and delete with same URI value.
Currently in spring-mvc repo, interceptors are invoked in DispatcherServlet#doDispatch(...):
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
...
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
try {
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
...
Can I define my own DispatcherServlet, and override doDispatch(...) to inject a HttpRequestWrapper with a ByteArrayInputStream on getInputStream()?
...
#Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
throws Exception {
RequestWrapper wrappedRequest = new RequestWrapper(request);
logger.debug("injecting RequestWrapper: " + wrappedRequest);
super.doDispatch(wrappedRequest, response);
}
...
Will this work for the above situation?
I make a Ouputstream version without any dependency to 3rd party libs for easier re-use. You can use this 2 wrapper class to get the request & response body easily.
But anyway, I have to use a filter to do this instead of interceptor. Because as #user1323865 mentioned, in spring 4, the processedRequest is used in both interceptor and handler, so you cannot use these methods for interceptor.
Also you can find some help in this link if you're using Writer version instead.
Capture and log the response body
public class BufferedRequestWrapper extends HttpServletRequestWrapper
{
private static final class BufferedServletInputStream extends ServletInputStream
{
private ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais)
{
this.bais = bais;
}
#Override
public int available()
{
return this.bais.available();
}
#Override
public int read()
{
return this.bais.read();
}
#Override
public int read(byte[] buf, int off, int len)
{
return this.bais.read(buf, off, len);
}
}
private byte[] mBodyBuffer;
public BufferedRequestWrapper(HttpServletRequest request) throws IOException
{
super(request);
InputStream in = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) > 0)
{
baos.write(buffer, 0, bytesRead);
}
mBodyBuffer = baos.toByteArray();
}
public String getRequestBody()
{
return new String(mBodyBuffer, Charset.forName("UTF-8"));
}
#Override
public BufferedReader getReader() throws IOException
{
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
#Override
public ServletInputStream getInputStream()
{
ByteArrayInputStream in = new ByteArrayInputStream(mBodyBuffer);
return new BufferedServletInputStream(in);
}
}
public class BufferedResponseWrapper extends HttpServletResponseWrapper
{
private TeeServletOutputStream mTeeOutputStream;
private static class TeeOutputStream extends OutputStream
{
private OutputStream mChainStream;
private OutputStream mTeeStream;
public TeeOutputStream(OutputStream chainStream, OutputStream teeStream)
{
mChainStream = chainStream;
mTeeStream = teeStream;
}
#Override
public void write(int b) throws IOException
{
mChainStream.write(b);
mTeeStream.write(b);
mTeeStream.flush();
}
#Override
public void close() throws IOException
{
flush();
mChainStream.close();
mTeeStream.close();
}
#Override
public void flush() throws IOException
{
mChainStream.close();
}
}
public class TeeServletOutputStream extends ServletOutputStream
{
private final TeeOutputStream targetStream;
public TeeServletOutputStream(OutputStream one, OutputStream two)
{
targetStream = new TeeOutputStream(one, two);
}
#Override
public void write(int b) throws IOException
{
this.targetStream.write(b);
}
#Override
public void flush() throws IOException
{
super.flush();
this.targetStream.flush();
}
#Override
public void close() throws IOException
{
super.close();
this.targetStream.close();
}
}
private ByteArrayOutputStream mByteArrayOutputStream;
public BufferedResponseWrapper(HttpServletResponse response) throws IOException
{
super(response);
mByteArrayOutputStream = new ByteArrayOutputStream();
mTeeOutputStream = new TeeServletOutputStream(super.getResponse().getOutputStream(), mByteArrayOutputStream);
}
#Override
public PrintWriter getWriter() throws IOException
{
return super.getResponse().getWriter();
}
#Override
public ServletOutputStream getOutputStream() throws IOException
{
return mTeeOutputStream;
}
public String getResponseBody()
{
return mByteArrayOutputStream.toString();
}
}
One simple way to do this would be to get the request body as String and then parse as a Java object. You can use this String then as you want.
So in your example:
#RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
#ResponseBody
public String updateEntity(#RequestBody String empAsString) {
// Do whatever with the json as String
System.out.println(empAsString);
// Transform it into the Java Object you want
ObjectMapper mapper = new ObjectMapper();
Employee emp = mapper.readValue(empAsString, Employee.class);
// Do some DB Stuff. Anyway, the control flow does not reach this place.
return "Employee " + emp.getName() + " updated successfully!";
}
As a note, if you need it as a list you can use:
List<Employee> eventsList =
mapper.readValue(jsonInString, mapper.getTypeFactory().constructCollectionType(List.class, Employee.class));
You need to implement the requestWrapper as follows:
public class DocVerificationRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public DocVerificationRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
#Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
#Override
public void setReadListener(ReadListener listener) {
// TODO Auto-generated method stub
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
and then inside the chain.doFilter method of filter class pass the requestWrapper object instead of the request object as follows:
#Override
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("checking token in filter");
HttpServletRequest request = (HttpServletRequest) arg0;
DocVerificationRequestWrapper myRequestWrapper = new DocVerificationRequestWrapper((HttpServletRequest) request);
String body = myRequestWrapper.getBody();
logger.info("body = "+body);
Token token = null;
try {
JSONObject jsonObj = new JSONObject(body);
JSONObject tokenObj = (JSONObject) jsonObj.get("token");
Gson gson = new Gson();
token = gson.fromJson(tokenObj.toString(), Token.class);
if(null != token) {
if(userVerificationService==null){
ServletContext servletContext = request.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
userVerificationService = webApplicationContext.getBean(UserVerificationService.class);
}
String verStatus = userVerificationService.verifyUser(token);
logger.info("verStatus = "+verStatus);
if(verStatus != null && verStatus.equalsIgnoreCase("success")) {
chain.doFilter(myRequestWrapper, response); //here replacing request with requestWrapper
}else
logger.error("Invalid token");
}else {
logger.error("token missing.");
}
} catch (JSONException e) {
logger.error("exception in authetication filter " + e);
}
}
Thus solving the IOStream closed exception.
For getting data from Body you can try to read and recreate InputStream in RequestBodyAdviceAdapter:
#ControllerAdvice
public class CustomRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {
#Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
String body = IOUtils.toString(inputMessage.getBody(), UTF_8.name());
HttpInputMessage myMessage = new HttpInputMessage(){
#Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream(body.getBytes());
}
#Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
};
System.out.println("Data from Body: " + body);
return super.beforeBodyRead(myMessage, parameter, targetType, converterType);
}
#Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
System.out.println("Data from Body is empty");
return super.handleEmptyBody(body, inputMessage, parameter, targetType, converterType);
}
#Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
}
#Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
}
You can simply use :
import org.apache.commons.io.IOUtils;
import java.nio.charset.Charset;
String requestBody = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8").toString());
In my experiences,just develop as follows:
Using the filter in order to wrapper ServletRequest,then you can repeatly use getting request input stream.