HttpServletRequest can not get xhr request parameter - javascript

I am working with Spring and javascript. Calling #Controller with XhrHttpRequest Object.
I can see my parameter(JSON string) with Chrome Inspector, but when I call request.getParamter("id") returns null.
Calling part with js
function ajax(url, data, callback, method){
//data is {"id":"system", "password" : "1234"}
var httpRequest;
var afterAction = function(){
if(!httpRequest) {
console.error('can not find httpRequest variable');
return;
}
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var responseData = httpRequest.responseText;
//alert(JSON.stringify(responseData));
console.log('Result of API call >>>', responseData);
if(typeof callback == 'function') {
callback(JSON.parse(responseData));
}
} else {
alert('There was a problem with the request.');
}
}
}
//=========== LOGIC ============
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
}
if(!method) method = 'POST';
data = (!!data) ? JSON.stringify(data) : '';
httpRequest.onreadystatechange = afterAction;
httpRequest.open(method.toUpperCase(), url, true);
httpRequest.setRequestHeader("Content-type", "application/json; charset=utf-8");
//httpRequest.setRequestHeader("Content-length", data.length);
//httpRequest.setRequestHeader("Connection", "close");
httpRequest.send(data);
}
receive part with Spring #Controller
#Controller
#RequestMapping(value={"member"}, produces={"application/json"})
#ResponseStatus(value = HttpStatus.OK)
public class MemberController {
/**
* #param request
* #param resp
* #return
* #throws Exception
*/
#RequestMapping(value={"/login"})
public #ResponseBody String login(HttpServletRequest request, HttpServletResponse resp) throws Exception {
System.out.println("Login request");
String id = String.valueOf(request.getParameter("id")); //returns null
String password = String.valueOf(request.getParameter("password")); //returns null
Map<String, String> result = new HashMap<String, String>();
result.put("result", "S");
result.put("message", "login success");
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(result);
}
}
I do not know why parameter becomes null. Thanks.

You need to follow the below steps to accept Json in your controller:
(1) Define UserLogin bean to hold the Json
public class UserLogin {
private String id;
private String password;
//Add getters and setters
}
(2) Change your controller to accept Json & receive the UserLogin bean
#Controller
#RequestMapping(value={"member"}, produces={"application/json"})
#ResponseStatus(value = HttpStatus.OK)
public class MemberController {
#RequestMapping(value={"/login"}, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String login(UserLogin userLogin) throws Exception {
System.out.println("Login request");
String id = userLogin.getId();
String password = userLogin.getPassword();
Map<String, String> result = new HashMap<String, String>();
result.put("result", "S");
result.put("message", "login success");
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(result);
}
}

This is an Alternative way with Jackson Library. I like #javaguy 's way, but using Jackson library could be more flexible so add this post.
Preparations
WebMvcConfigurerAdapter implements class or something equivalent with that
SpringFramework Environment. In my case, Eclipse Dynamic Web Project with Maven and spring-webmvc in pom.xml.
What I did...
Implement WebMvcConfigurerAdapter
Override Method configureMessageConverters
Change Controller parameters from HttpServeletRequest request, HttpServletResponse resp to #RequestBody Map<?, ?>.(You can change generic value. It does not matters for further process)
So Here's code.
ServerConfig.java (I block other Options to focus current issue)
#Configuration
#EnableWebMvc
#ComponentScan(basePackages={ ... }
, excludeFilters=#ComponentScan.Filter(Configuration.class))
//Filter 걸 때 Configuration.class 를 수동으로 등록해줘야 되는데 나은 방법 찾아보기
public class ServerConfig extends WebMvcConfigurerAdapter {
...
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
};
And Controller (Change Parameter Types)
#Controller
#RequestMapping(value={"member"}, produces={"application/json"})
#ResponseStatus(value = HttpStatus.OK)
public class MemberApiController {
...
#RequestMapping(value={"/login"})
public #ResponseBody String login(#RequestBody Map<?, ?> jsonBody) throws JsonProcessingException {
System.out.println("Login request" + jsonBody.toString());
Map<String, String> result = new HashMap<String, String>();
String rs = "S";
String message = "SUCCESS";
System.out.println("ID >>> ", String.valueOf(jsonBody.get("id")));
System.out.println("PW >>> ", String.valueOf(jsonBody.get("password")));
result.put("result", rs);
result.put("result_msg", message);
mapper = new ObjectMapper();
return mapper.writeValueAsString(result);
}
};
However, since as far as I know #RequestBody does not have HttpSession, If you try to store data to HttpSession, you need another parameter HttpServletRequest.
I hope this could be a hand to others who has same problem with me :D

Related

Pass JSON Object through Jquery GET call to Java Servlet

how can i pass a JSON Array/Object with the JQUERY get Method to my Java Servlet?
So far , here's my code:
var json = {
MA_ID : $("#emplID").val(),
MA_Nachname : $("#nachname").val()
}
$.get(url + "/MA_Update", json)
[...]
MA_Update.java
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuffer jb = new StringBuffer();
String line = null;
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
try {
JSONObject jsonObject = HTTP.toJSONObject(jb.toString());
System.out.println(jsonObject);
} catch (JSONException e) {
// crash and burn
throw new IOException("Error parsing JSON request string");
}
}
But I only get
{"Request-URI":"","Method":"","HTTP-Version":""}
from my request
Do not use request.getReader(), use request.getParameter("MA_ID") etc., or request.getParameterMap() (and iterate over it).
The thing is, that $.get(url, jsObject) creates a HTTP GET request, where the fields of the jsObject are transformed into query parameters, i.e. http://your.server.com/MA_Update?MA_ID=someID&MA_Nachname=SomeLastName, so they are NOT available in the request body (as they would be in a POST request).

HTTP Post from Postman working but not through browser

I am using JaxRS jersey for server and I have deployed it on aws. Http post request to server is working with postman but not with Http post apache client.
Following is my Java for Rest service
#Path("/data")
public class MyResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<trackerdetails> getIt() {
SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();
Session session = sessionfactory.openSession();
session.beginTransaction();
trackerdetails user = new trackerdetails();
List<trackerdetails> sendlist = (List<trackerdetails>) session.createQuery("from trackerdetails").list();
session.getTransaction().commit();
session.close();
return sendlist;
}
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public trackerdetails putit(trackerdetails track) {
track.setDate(new Date());
SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory();
Session session = sessionfactory.openSession();
session.beginTransaction();
session.save(track);
session.getTransaction().commit();
session.close();
return track;
}
Following is my trackerdetails class
#Entity
#XmlRootElement
public class trackerdetails {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int autoid;
private String latitude;
private String longitude;
private String devicename;
private Date date;
public trackerdetails(){
}
public int getAutoid() {
return autoid;
}
public void setAutoid(int autoid) {
this.autoid = autoid;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getDevicename() {
return devicename;
}
public void setDevicename(String devicename) {
this.devicename = devicename;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
Following is my Client side http post request
HttpPost httpPost = new HttpPost("myurl");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("devicename", "vip"));
nvps.add(new BasicNameValuePair("date", "hjksvn"));
nvps.add(new BasicNameValuePair("latitude", "hello"));
nvps.add(new BasicNameValuePair("longitude","hi"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
httpPost.setHeader("Cache-Control", "no-cache");
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("Host", "trackertest.herokuapp.com");
CloseableHttpResponse response2 = httpclient.execute(httpPost);
try {
System.out.println(response2.getStatusLine());
System.out.println(response2.toString());
HttpEntity entity2 = response2.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
BufferedReader rd = new BufferedReader(
new InputStreamReader(response2.getEntity().getContent()));
StringBuffer result1 = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result1.append(line);
System.out.println(line);
System.out.println("");
}
System.out.println(result1);
EntityUtils.consume(entity2);
} finally {
response2.close();
}
Following is my error status is 400
Bad Requestdescription The request sent by the client was syntactically incorrect.
Your REST API expects request in JSON format but the way you are constructing request body using NameValuePair will not result in JSON format.
You should make a valid JSON request body either by using some libraries which can convert object into JSON like Jackson or you can manually construct JSON request body and then call your API.
Below is one way of manually constructing JSON request body -
HttpPost httpPost = new HttpPost("myurl");
StringBuilder jsonBody = new StringBuilder();
jsonBody.append("{");
jsonBody.append("\"devicename\" : ").append("\"vip\"").append(",");
// Pass a valid date because on server side, you are using Date object for accepting it
jsonBody.append("\"date\" : ").append("\"2017-09-23\"").append(",");
jsonBody.append("\"latitude\" : ").append("\"vip\"").append(",");
jsonBody.append("\"longitude\" : ").append("\"vip\"");
jsonBody.append("}");
StringRequestEntity requestEntity = new StringRequestEntity(jsonBody.toString(),"application/json","UTF-8");
httpPost.setRequestEntity(requestEntity);
httpPost.setHeader("Cache-Control", "no-cache");
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("Host", "trackertest.herokuapp.com");
// Rest code should remain same

How to pass parameters to controller using ajax and javascript?

I am trying to delete an item from shopping cart using Ajax with javascript, but I have trouble passing parameters to the controller. The parameters are null in controller.
My javascript code shows as below:
function removeRow(itemId, rowID){
if (xmlHttp == null)
{
alert("Your browser does not support AJAX!");
return;
}
var query = "action=remove&item=" + itemId;
/* alert(query); */
xmlHttp.onreadystatechange = function stateChanged()
{
if (xmlHttp.readyState == 4)
{
var row = document.getElementById(rowID);
row.parentNode.removeChild(row);
}
};
xmlHttp.open("GET", "addTo.htm", true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send(query);
return false;
/* var row = document.getElementById(rowID);
row.parentNode.removeChild(row); */
}
My controller code shows as below:
#Controller
#RequestMapping("/addTo.htm")
public class AddToController{
#RequestMapping(method=RequestMethod.GET)
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
String action = request.getParameter("action");
System.out.println(action);
ModelAndView mv = new ModelAndView();
ArrayList<Item> cart;
if(action.equals("remove")){
System.out.println("cart size is" + cart.size());
Long itemId = Long.parseLong(request.getParameter("item"));
ItemDAO itemDao= new ItemDAO();
Item item = itemDao.get(itemId);
cart.remove(item);
System.out.println(cart.size());
}
return mv;
}
}
The action and item are null in the controller.
Can anyone help with this problem?
You're sending a GET request, so add the parameters as a query after your URL:
xmlHttp.open("GET", "addTo.htm?" + query, true);
and pass in null (rather than your query string) when calling the .send method:
xmlHttp.send(null);
Also, the "application/x-www-form-urlencoded" header is only used when you're sending serialised parameters but using POST, so remove the xmlHttp.setRequestHeader line.
More info: https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started

Issue populating Textview with data from website via URL

I'm trying to read a line of text from a URL and display the result in a Textview.
ISSUE/ERROR:
At present there is no error, the textview is not populated after I execute DownloadWebPage Async task.
INVESTIGATIONS
I believe I may not be calling this correctly, as I can't find any results from my debug calls, in DownloadWebPage. Also my URL has one line of code with two strings, if that makes any difference.
UPDATE:
In DownloadWebPage my logs commands are not showing in the log files - weird
CODE: ON CREATE:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox_list);
textView = (TextView) findViewById(R.id.textView6);
// Hashmap for ListView
inboxList = new ArrayList<HashMap<String, String>>();
//ASYNC TASK I CREATED
new DownloadWebPageTask().execute();
// Another Async Task in my code
new LoadInbox().execute();
}
CODE: AsyncTask for Parsing Data from URL & Setting Data to Textview
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(Html.fromHtml(result));
}
}
public void readWebpage(View view) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.url.com/blah.php" });
}

Unable to get data at first click in android webview with server communication

I am calling this method from JavaScript.
For the first time, it is giving null. But from the second time onwards, the data is coming.
Please help me.
#SuppressLint("JavascriptInterface")
public String loadClickedData() {
pDialog = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new HttpAsyncTaskClickedData()
.execute("http://192.168.0.9/btrepo/btrepo/android_api.php");
return bdb.getmPosIdData();
}
Here we are getting data through AsyncTask in Android:
private class HttpAsyncTaskClickedData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("tag", "get_pos_details"));
nameValuePairs.add(new BasicNameValuePair("pos_id", posId));
return GET(urls[0], nameValuePairs);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
// Toast.makeText(getApplicationContext(), result+" in post ",
// Toast.LENGTH_LONG).show();
pDialog.dismiss();
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG)
.show();
bdb.setmPosIdData(result);
}
}
This method is for getting data from the server:
public static String GET(String url, List<NameValuePair> pair) {
InputStream inputStream = null;
String result = "";
try {
// create HttpClient
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pair));
HttpResponse httpResponse = httpClient.execute(httpPost);
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
is = inputStream;
// convert inputstream to string
if (inputStream != null) {
// jObj = convertIsToJson(inputStream);
result = convertIsToJson(inputStream) + " ";
// jSonStr = result;
} else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return result;
}
I am getting data from the server in json string format.
It is displaying attributes with null value like {pos["posid":null, "storeName":null]} etc..
In the following function
public String loadClickedData() {
pDialog = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new HttpAsyncTaskClickedData()
.execute("http://192.168.0.9/btrepo/btrepo/android_api.php");
return bdb.getmPosIdData();
}
You execute your HttpAsyncTaskClickedData(), and return bdb.getmPosIdData() immediately. (Which will always be an issue for the 1st time)
The result of the AsyncTask is only available in onPostExecute, where you call bdb.setmPosIdData(result);.
#Override
protected void onPostExecute(String result) {
// ...
bdb.setmPosIdData(result); // result is only stored in bdb here!
}
The HttpAsyncTaskClickedData runs in the background, and possibly takes some time.
That is why your first call is always unable to get data, as you returned bdb.getmPosIdData() immediately after executing your AsyncTask.
private class HttpAsyncTaskClickedData extends
AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs
.add(new BasicNameValuePair("tag", "get_pos_details"));
nameValuePairs.add(new BasicNameValuePair("pos_id", posId));
return GET(urls[0], nameValuePairs);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
// Toast.makeText(getApplicationContext(), result+" in post ",
// Toast.LENGTH_LONG).show();
data = result;
pDialog.dismiss();
bdb.setmPosIdData(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(MainActivity.this, "dialog title",
"dialog message", true);
}
#SuppressLint("JavascriptInterface")
public String loadData() {
Toast.makeText(getApplicationContext(), data+ " hi ",
Toast.LENGTH_LONG).show();
return data;
}
}
and calling loadData() method from javascript.
This function is for get data by using post url in javascript
function jsonPost(){
var http = new XMLHttpRequest();
var url = "http://192.168.0.9/btrepo/btrepo/android_api.php";
var params = "tag=fav_stores&mobile=984989874";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
alert("hello "+http.send(params));
}

Categories