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
Related
I have a situation in which I want to select all records from a database given a specific id. The request is first sent from JavaScript, which is received by a Servlet which accesses a DAO that in turn queries a database. The data will then, obviously, make its way back to the front-end. I'm just a little cloudy on passing these parameters along so that the database is queried correctly.
I am currently getting a 500 error which is due to my parameters not being passed along correctly.
Starting at the JavaScript with the initial request:
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/project1attempt/reimbursement?
employee_id=' + x._id, true);
xhr.send();
Receiving the parameters at the Servlet is my biggest point of confusion, therefore the code here is incomplete (rs is a Reimbursement Service):
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("application/json");
int id = ;
List<Reimbursement> reimbursements = rs.findAllReimbursements(id);
String json = new ObjectMapper().writeValueAsString(reimbursements);
resp.getWriter().write(json);
}
And the query:
public List<Reimbursement> findAllReimbursements(int id) {
List<Reimbursement> reimbursements = new ArrayList<>();
try
(Connection c = manager.getConnection()) {
String sql = "SELECT reimbursement_id, date, description, amount,
typing_id, employee_id" +
"FROM reimbursements" +
"WHERE reimbursement_id = ?";
PreparedStatement ps = c.prepareStatement(sql);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
Reimbursement r = null;
while (rs.next()) {
r = new Reimbursement();
r.setId(rs.getInt("reimbursement_id"));
r.setDate(rs.getDate("date"));
r.setDescription(rs.getString("description"));
r.setAmount(rs.getDouble("amount"));
r.setTypingId(rs.getInt("typing_id"));
r.setEmployeeId(rs.getInt("employee_id"));
reimbursements.add(r);
}
return reimbursements;
} catch (SQLException e) {
throw new BlabApplicationDataException("Could not connect to
Reimbursement Repository" + id);
}
}
You can use getParameter method of HttpServletRequest to get the URL parameter you need.
Probably, this is the line you are looking for.
String idStr = req.getParameter('employee_id');
if(idStr != null) {
int id = Integer.parseInt(idStr);
}
I'm trying to send an array of JavaScript objects to my ASP.Net MVC controller without using jQuery. I have a simple array of JavaScript objects like this...
var data = [];
data.push(new person(1, "David"));
data.push(new person(2, "Karine"));
data.push(new person(2, "Annie"));
...etc
function person(_id, _name) {
this.id = _id;
this.name = _name;
}
...and I would like to have it as a parameter of an ajax call like this:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var obj = JSON.parse(xmlhttp.responseText);
for (var i = 0; i < obj.length; i++) {
if (i == 1) {
alert(obj[i].name);}
}
}
else {
alert('There is an error');
}
}
};
xmlhttp.open("GET", "/Home/AjaxTester?id=15&name=dave", true);
xmlhttp.send();
The way I found so far to pass parameters to an ajax call, which is ...Home/AjaxTester?id=15&name=dave, works fine for basic types, but I can't find a way to do the same with more "complex" types. I'm open to new ways to parameterize my ajax call if anything better, or even a new way to make an ajax call, as long as it is pure JavaScript, no library, no framework, or whatever.
Here's my MVC controller...
public JsonResult AjaxTester(List<Person> _person)
{
//Whatever Logic...
return Json(_someObjects);
}
...and the class of the received parameter
public class Person
{
public int id { get; set; } = 0;
public string name { get; set; } = "";
public Person(int _id, string _name)
{
this.id = _id;
this.name = _name;
}
}
You need to have FromUri command before parameters, like this:
public JsonResult AjaxTester(FromUri List<Person> _person)
You need to change your http method from GET to POST.
xmlhttp.open("POST", "/Home/AjaxTester?id=15&name=dave", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(JSON.stringify(data));
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Make sure you add the setRequestHeader. If you are sending a json object then change the request header to the following:
xhr.setRequestHeader("Content-type", "application/json");
I would also recommend removing the query parameter and updating the controller to accept this type of object. You may also need to add the [FromBody] in next to that parameter.
And your controller should be updated similar to
public JsonResult AjaxTester([FromBody] List<Person> _person)
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
I have a ASP.NET Web application and a Classic ASP Page which calls a WCF Service and gets a composite type R as response.
The ASP.NET Web application gets the composite object (R) and does the following:
if(R.IsValid)
{
Response.Clear();
Response.ContentType = contentType;
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", fileName));
Response.AddHeader("Content-Length", R.ByteArray.Length.ToString());
Response.BinaryWrite(R.ByteArray);
Response.End();
}
The Classic ASP Page gets the response too.
How do I cast it to the Composite type R(with IsValid and ByteArray)?
How do I do the operations that one can do the Response object in .NET with the ServerXMLHTTP object in javascript?
UPDATE:
function CallWcfAjax()
{
var xmlHttp = new ActiveXObject("Microsoft.XmlHttp");
var url = "http://localhost:54329/DocumentGeneratorService.svc/ajaxEndpoint/";
url = url + "GetDetailsMessageUsingPost";
var xmlContents = loadXML("Data.xml");
var getDetailsMessageUsingPostBody = '<GetDetailsMessageUsingPost><input>';
getDetailsMessageUsingPostBody = getDetailsMessageUsingPostBody + xmlContents;
getDetailsMessageUsingPostBody = getDetailsMessageUsingPostBody + '</input></GetDetailsMessageUsingPost>';
// Send the HTTP request
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "text/xml; charset=utf-8");
xmlHttp.send(getDetailsMessageUsingPostBody);
// Create result handler
xmlHttp.onreadystatechange= function X()
{
if (xmlHttp.readyState == 4)
{
result.innerText = xmlHttp.responseText;
// TODO: Handle xmlHttp.responseStream or other property
}
}
}
This is my javascript part
<script language=javascript type="text/javascript">
function myFunction() {
var request = new XMLHttpRequest();
request.open("GET", "http://localhost:8080/Test/Servlet");
request.send();
//document.write("Request GET enviado!");
}
</script>
This is my doGEt part
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Request GET recebido!");
// JDBC driver name and database URL
String JDBC_DRIVER = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://localhost:3306/Tests";
// Database credentials
String USER = "fabio";
String PASS = "hacking";
Connection conn = null;
Statement stmt = null;
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
// Register JDBC driver
Class.forName(JDBC_DRIVER);
// Open a connection
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// Execute SQL query
stmt = conn.createStatement();
String sql;
sql = "SELECT * FROM people";
ResultSet rs = stmt.executeQuery(sql);
out.println("<html><body>");
// Extract data from result set
while (rs.next()) {
//Retrieve by column name
int person_id = rs.getInt("person_id");
String first_name = rs.getString("first_name");
String last_name = rs.getString("last_name");
//Display values
out.println("Person ID: " + person_id + " | ");
out.println("First name: " + first_name + " | ");
out.println("Last name: " + last_name + "<br>");
}
out.println("</body></html>");
// Clean-up environment
out.close();
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
System.out.println(e);
}
}
They work until the point that data is retrieved from DB. The part that does not work is posting the out.println back to HTML page. Could someone please advise?
Thanks,
It is not obvious for me from the question if you did anything with the response like this:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
var respdiv = document.getElementById("respdiv");
respdiv.innerHTML = "Response=" + xhr.responseText;
}
xhr.open("GET", "http://localhost:8080/Test/Servlet", true);
xhr.send(null);
Also it was interesting that running in built in eclipse browser it responded with "hello" instead of "SOMETHING" (did not check why) but worked when opened in chrome.
doGet code:
PrintWriter out = response.getWriter();
out.println("SOMETHING");
out.flush();
out.close();