How to send and catch parameter from JavaScript (AJAX request) to Servlet - java

I created InformationServlet that whenever I need some details I can send it what I want (with AJAX) and it will return me the information.
I searched how to do it on Ajax and according to:
How to send parameter to a servlet using Ajax Call
I used: url: "InformationServlet?param=numberOfPlayers"
But on the servlet the request's attributes doesn't contain the parameter I sent so I suppose I am not doing it correctly:
you can see that the attributes size is zero
Servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
Gson gson = new Gson();
Engine engine = (Engine)getServletContext().getAttribute("engine");
String responseJson = "";
if(request.getAttribute("numberOfPlayers") != null)
{
String numberOfPlayers = "";
numberOfPlayers = gson.toJson(String.valueOf(engine.GetNumOfPlayers()));
responseJson = numberOfPlayers;
}
out.print(responseJson);
} finally {
out.close();
}
}
JavaScript (AJAX request):
function getNumberOfPlayersAndPrintSoldiers()
{
$.ajax({
url: "InformationServlet?param=numberOfPlayers",
timeout: 2000,
error: function() {
console.log("Failed to send ajax");
},
success: function(numberOfPlayers) {
var r = numberOfPlayers;
}
});
}

Edit:
you probably want to use getParameter and not getAttribute
Moreover, please pay attention to the order of parameter name and his value:
request.getParameter("param");
instad of:
request.getParameter("numberOfPlayers");
because the url form contains parameter name first and then the parameter value. for example:
myurl.html?param=17
and if more parameters needed then use the separator & sign
myurl.html?firstName=bob&age=5

Related

How to write more then one method inside one servlet

I am working on ajax for getting data from my server as back-end i am using java-servlets
Now what issues i am facing is:
i have to call two data for two different work via ajax
So what i am doing currently is creating two servlet class and making two ajax call to both of them
i am writing all my codes in doGet method of one servlet
and via ajax call in url i am giving servlet class name
What i am trying to do
can't i create one servlet and inside it i can make several methods and make ajax call on that servlet class method
what i am doing
Servlet1 code
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String categoryCode, categoryName, quantity,sql,str = null;
Gson gson = new Gson();
LinkedHashMap<Object, Object> lhm = null;
LinkedList<LinkedHashMap<Object, Object>> mainList = new LinkedList<LinkedHashMap<Object, Object>>();
try {
sql = "1";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
lhm = new LinkedHashMap<Object, Object>();
categoryCode = "A101";
categoryName = "drinks";
lhm.put("Category Code", categoryCode);
lhm.put("Category Name", categoryName);
mainList.add(lhm);
str = gson.toJson(mainList);
}
response.setContentType("application/json");
response.getWriter().write(str);
}}
Servlet2 code
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String itemName, itemCode, quantity,sql,str = null;
Gson gson = new Gson();
LinkedHashMap<Object, Object> lhm = null;
LinkedList<LinkedHashMap<Object, Object>> mainList = new LinkedList<LinkedHashMap<Object, Object>>();
try {
sql = "2";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
lhm = new LinkedHashMap<Object, Object>();
itemName = "pepsi";
itemCode = "AA00";
lhm.put("Item Code", itemCode);
lhm.put("Item Name", itemName);
mainList.add(lhm);
str = gson.toJson(mainList);
}
response.setContentType("application/json");
response.getWriter().write(str);
}
and my ajax call code
$.ajax({
async: true,
url : "Servlet1",
method : "GET",
dataType : "json",
contentType: "application/json; charset=utf-8",
success : function(tableValue) {
addTable(tableValue)
}
});
Now i have to get data from my data base and run 2 queries and have to do two different thing with there result,but doing it with creating new-new servlets now dosn't looks good
Can't i create one doGet and inside that two methods or any two methods inside servlet so that both the servlet codes can be written in oneservlet
Note :- i don't have knowledge on spring framework , so i want to do it with help of servlets only
anyone please guide me how can i do that
Thanks in advance
There isn't a good solution for HttpServlet classes, as you can only have one doGet method. A decent workaround would be adding a parameter in your url, for example Servlet1?action=action1 and then implementing logic in your doGet()
method to decide what to do based on that parameter. For example:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
switch(action){
case "action1":
doAction1(request, response); //Method with the logic of your Servlet1 class
break;
case "action2":
doAction2(request, response);
break;
default:
throw new ServletException("Invalid action parameter");
}
}
Edit - this would be your final ajax call:
$.ajax({
async: true,
url : "Servlet1?action=action1", // Here you set the parameter
method : "GET",
dataType : "json",
contentType: "application/json; charset=utf-8",
success : function(tableValue) {
addTable(tableValue)
}
});

Multipart request giving issues when received in rest service

I am trying to upload a file using multipart request through angularjs and receive the content on my Rest service. I am putting up this question here after trying several helps for last 4 days and tiring myself to utmost level. I would appreciate if you can fine tune my approach or suggest another approach (I am open to any suggestions which may work as I am out of ideas now).
Just a pointer, I have tried writing a servlet to read the multipart request sent through angularjs and I got the parts correctly. But I am still putting the angular code here for your reference as I am not better on both angular and rest.
Following is the html extract for file upload:
<div>
<input type="file" data-file-upload multiple/>
<ul>
<li data-ng-repeat="file in files">{{file.name}}</li>
</ul>
</div>
Followingis the angularjs directive code extract:
.directive('fileUpload', function () {
return {
scope: true, //create a new scope
link: function (scope, el, attrs) {
el.bind('change', function (event) {
var files = event.target.files;
//iterate files since 'multiple' may be specified on the element
for (var i = 0;i<files.length;i++) {
//emit event upward
scope.$emit("fileSelected", { file: files[i] });
}
});
}
};
})
Following is the angularjs controller code extract
//a simple model to bind to and send to the server
$scope.model = {
name: "test",
comments: "TC"
};
//an array of files selected
$scope.files = [];
//listen for the file selected event
$scope.$on("fileSelected", function (event, args) {
$scope.$apply(function () {
//add the file object to the scope's files collection
$scope.files.push(args.file);
});
});
//the save method
$scope.save = function() {
$http({
method: 'POST',
url: "/services/testApp/settings/api/vsp/save",
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append("model", angular.toJson(data.model));
for (var i = 0; i < data.files.length; i++) {
formData.append("file" , data.files[i]);
}
return formData;
},
data: { model: $scope.model, files: $scope.files }
}).
success(function (data, status, headers, config) {
alert("success!");
}).
error(function (data, status, headers, config) {
alert("failed!");
});
};
And here is my rest service code:
#Path("/vsp")
public class SampleService{
#Path("/save")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void saveProfile(#FormParam("model") String theXml,
#FormParam("file") List<File> files) throws ServletException, IOException {
final String response = "theXML: " + theXml + " and " + files.size() + " file(s) received";
System.out.println(response);
}
}
And here is the response:
theXML: {"name":"test","comments":"TC"} and 1 file(s) received
The problem is that the content of the file is coming in path and I am not able to get the input stream to read the file. I even tried using
new ByteArrayInputStream(files.get(0).getPath().getBytes())
If the content is text (like txt or csv) it works, but if the content is any other file like xls etc, the retrieved content is corrupt and unusable. Also tried using Jeresy api, but with same result. Am I missing anything obvious? Any help is appreciated.
I came across a few links, but none worked for me. So finally, I had to write a servlet to read the multipart request and added the files and the request parameters as request attributes. Once the request attributes are set, I forwarded the request to my Rest service.
Just for the record, if the multipart request is read once to extract the parts, the request will not have the parts in the forwarded servlet. So I had to set them as request attributes before forwarding.
Here is the servlet code:
public class UploadServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// process only if its multipart content
RequestContext reqContext = new ServletRequestContext(request);
if (ServletFileUpload.isMultipartContent(reqContext)) {
try {
List<FileItem> multiparts = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest(request);
ArrayList<FileItem> fileList = new ArrayList<FileItem>();
request.setAttribute("files", fileList);
for (FileItem item : multiparts) {
if (!item.isFormField()) {
fileList.add(item);
} else {
request.setAttribute(item.getFieldName(),
item.getString());
}
}
request.setAttribute("message", "success");
} catch (Exception ex) {
request.setAttribute("message", "fail"
+ ex);
}
} else {
request.setAttribute("message",
"notMultipart");
}
System.out.println(request.getRequestURI().substring(request.getRequestURI().indexOf("upload")+6));
String forwardUri = "/api" + request.getRequestURI().substring(request.getRequestURI().indexOf("upload")+6);
request.getRequestDispatcher(forwardUri)
.forward(request, response);
}
}
Any request starting with /upload/<rest api path> will be received by the servlet and once the attributes are set, they will be forwarded to /api/<rest api path>.
In the rest api, I used the following code to retrieve the parameters.
#Path("/vsp")
public class SampleService{
#Path("/save")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void saveProfile(#Context HttpServletRequest request,
#Context HttpServletResponse response) throws Exception {
// getting the uploaded files
ArrayList<FileItem> items = (ArrayList<FileItem>)request.getAttribute("files");
FileItem item = items.get(0);
String name = new File(item.getName()).getName();
item.write( new File("C:" + File.separator + name));
// getting the data
String modelString = (String)request.getAttribute("model");
// Getting JSON from model string
JSONObject obj = JSONObject.parse(modelString);
String responseString = "model.name: " + obj.get("name") + " and " + items.size() + " file(s) received";
System.out.println(responseString);
}
}

Passing custom objects from servlet to Jquery

i have a servlet my goal is to return a customer object from the process request, where i can then access this object in my jquery. Does anyone know how i can go about doing this?
e.g. myObject.getMethod()
Servlet Code:
Customer loginResult;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/* TODO output your page here. You may use following sample code. */
//request.setAttribute("customerFirstName", loginResult.getFirstName()); //String Value
//request.setAttribute("customerID", loginResult.getCustomerID()); //IntegerValue
out.println(loginResult);
} finally {
out.close();
}
}
JSP CODE:
<script type="text/javascript">
$().ready(function() {
$('#submit').click(function() {
var dataf = 'email=' + $('#email').val()
+ '&password=' + $('#password').val();
$.ajax({
url: "http://localhost:8080/RetailerGui/loginServlet",
type: "get",
data: dataf,
success: function(data) {
alert(data);
}
});
return false;
});
});
</script>
Can someone please assist me in resolving this issue, thank you for your help in advance.
Since you want to handle an ajax request using a Servlet, the best bet you have is writing the data of your custom object into the response. The easier way I found to accomplish this is using JSON. There are lot of libraries that handles JSON conversion from objects to Strings and vice versa, I recommend using Jackson. This is how your code should look like.
Servlet code:
import com.fasterxml.jackson.databind.ObjectMapper;
#WebServlet("/loginServlet") //assuming you're using Servlet 3.0
public class YourServlet extends HttpServlet {
//Jackson class that handles JSON marshalling
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
//login operation should be handled in POST
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Customer loginResult = ...; //process data and get the loginResult instance
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
//marshalling the data of your loginResult in JSON format
String json = OBJECT_MAPPER.writeValueAsString(loginResult);
response.getWriter().write(json);
}
}
Javascript code:
<script type="text/javascript">
$().ready(function() {
$('#submit').click(function() {
var dataf = 'email=' + $('#email').val()
+ '&password=' + $('#password').val();
$.ajax({
url: "http://localhost:8080/RetailerGui/loginServlet",
type: "post", //login action MUST be post, NEVER a get
data: dataf,
success: function(data) {
//shows the relevant data of your login result object in json format
alert(data);
//parsing your data into a JavaScript variable
var loginResult = JSON && JSON.parse(data) || $.parseJSON(data);
//now you can use the attributes of your loginResult easily in JavaScript
//for example, assuming you have a name attribute in your Customer class
alert(loginResult.name);
}
});
return false;
});
});
</script>
More info:
How to use Servlets and Ajax?
Parse JSON in JavaScript?

How to pass parameters to servlet using Ext.Ajax.request?

I have an extjs form from which I am trying to post parameter using Ext.Ajax.request to the servlet. Call is working and servlet is being called but for some reason parameter's value isn't being send. I'll post my code, can anyone tell me what I am doing wrong. Thanks in advance.
This is the call from ExtJS form:
buttons: [{
text: 'Search',
handler: function(){
var fName = Ext.getCmp("fName").getValue();
Ext.Ajax.request({
url : 'LookUPCustomer',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
params : fName, // this value isn't being passed to servlet
success: function ( result, request ) {
var resultData1 = JSON.parse(result.responseText);
},
failure: function ( result, request ) {
resultData = JSON.parse(xmlhttp.responseText);
}
});
}];
and here is servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// value of fName is null, not being passed from the form
String fName = request.getParameter("fName");
// does some processing....
// print back to the form
response.setContentType("application/json");
out.println(jsArray);
}
The params parameter should be a JSON object with key, value pairs. Here's an example:
params: {
firstName: 'Jeff',
lastName: 'Tester'
}
or to plug in your variable
params: { fName: fName }
As you said, u are using extjs 4.0.7. it uses extraparams.
So you need to code like below
Before sending just validate whether fName contain required value.
Ext.Ajax.request({
url : <URL>,
method: 'POST',
extraParams :{ fName : fName },
success: function ( result, request ) {
var resultData1 = JSON.parse(result.responseText);
},
failure: function ( result, request ) {
resultData = JSON.parse(xmlhttp.responseText);
}
});
Thanks

jquery ajax call returns error on successful call to a servlet

I have a servlet that adds a user to a file on the server side.
I invoke it with a jqueries ajax call.
I can see on the server that the method is being called correctly and my user is added, but the error callback is being invoked on the jquery call. All the status text says is error.
Using firebug the response seems to be empty. Why can I not get a success jquery callback?
//Servlet Code
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
String responseStr = "";
if(action.equals("addUser"))
{
responseStr = addUser(request);
}
System.out.println("Reponse:" + responseStr);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().println(responseStr);
}
private String addUser(HttpServletRequest request) throws IOException
{
Storage s;
s = Storage.load();
String name = request.getParameter("name");
String imageUrl = request.getParameter("imageUrl");
User u = new User();
u.setName(name);
u.setImageUrl(imageUrl);
s.addUser(u);
s.save();
return "success";
}
.
//javascript code
function addUser() {
var name = $('#name').val();
var imageUrl = $('#imageUrl').val();
var url = "http://ws06525:8080/QCHounds/QCHoundServlet?action=addUser&name=${name}&imageUrl=${imageUrl}";
url = url.replace("${name}", name);
url = url.replace("${imageUrl}", imageUrl);
$('#result').html(url);
$.ajax({
url: url,
success: function( data ) {
$('#result').html(data);
},
error: function(jqXHR, textStatus, errorThrown)
{
alert("error: " + textStatus);
alert("error: " + errorThrown);
}
});
}
Aaargh! Feel like an idiot. It's a cross site scripting issue.
I was testing the call to the server from the html file on disk so my browser address was
file://projects/myproject/content/Users.html <<< Fail
instead of:
http://myboxname:8080/appname/Users.html <<< Works
The actual code is fine...
use this for learn what is the problem, it will be better for get solution i think
error: function(e){
alert(JSON.stringify(e))
}
For one thing the string "success" isn't valid json. If your ajax query is expecting json, that would fail it.
What if you returned "{ \"success\": true }" ?
EDIT
It looks like from your ajax call that the response shouldn't be json, why is your return content type json?
If it is true that firebug shows no response, your problem must be in the java code that writes the response.

Categories

Resources