I need to call a bean method in JavaScript and/or jQuery,and have to make decisions depending upon the value returned by method.
How can we do this?
In order for JavaScript and a Java Servlet to be able to talk, as you suggested you will need an AJAX call, which you can do with jQuery.
First, setup a new Servlet which will act as an AJAX web service of sorts. We'll keep it simple, so just implement the doGet() method to handle HTTP GET requests. In that GET method, have a look at the query string for specific arguments.
Example:
myServlet?myArgument1=value1
(Make sure your web.xml maps your Servlet to /myServlet in this example)
Process the request in your Java code (get the value from your bean), then build a JSON response based on that. For instance, you could return:
{ "response": "my value" }
The Java side is done.
On the JavaScript side, you will need to launch a $.getJSON() query.
You would do this in the following way:
var myRequest = $.getJSON("myServlet?myArgument1=" + value1,
function(data)
{
console.log( "success" );
// Process the 'data', which is the JSON response.
var returnedJson = JSON.parse(data);
var value = returnedJson.response; // now equals "my value"
// ...
})
.fail(function()
{
// Handle errors here
console.log( "error" );
})
.always(function()
{
// If you need to do something whether the request was success or fail,
// do it here.
console.log( "complete" );
});
In my opinion that would be the most straightforward way to do it. If you're looking for a Java library that will easily let you parse or create JSON, instead of 'hard-coding' it, you can have a look at json-smart.
https://code.google.com/p/json-smart/
Related
I have an array in JS and I am trying to pass it as parameter to URL and catch it in PHP but I cant get to understand how to do it:
var trafficFilterHolder = ["roadworks","snow","blocking"];
var filters = encodeURI(JSON.stringify(trafficFilterHolder));
FYI: I am using windows.fetch for posting.
in PHP:
$trafficFilters = $_GET["trafficFilters"];
$obj = json_decode($trafficFilters);
var_dump($obj);
You are passing the data to php with fetch() intead of ajax, so the alternative of my first answer to do the same with the fetch() is:
var trafficFilterHolder = ["roadworks","snow","blocking"];
var trafficFilterHolderJoin = trafficFilterHolder.join(); // comma-separeted format => "roadworks,snow,blocking"
Now add the trafficFilterHolderJoin variable to the traffic query of the URL of your fetch(), like:
fetch('script.php?traffic=' + trafficFilterHolderJoin)
Then in your php script file you will convert the comma-separeted format to php array format using the explode function:
$traffic = explode(",", $_GET['traffic']);
It's quite simple, you are passing these data to php with ajax, correct?
First of all, you are creating the javascript array incorrectly:
var trafficFilterHolder = [0: "roadworks", 1: "snow", 2: "blocking"];
Don't use brackets to create arrays with keys, use this format instead:
var trafficFilterHolder = {0: "roadworks", 1: "snow", 2: "blocking"};
Now, in the ajax, just add the array in the data:
$.ajax({
data: { trafficFilters: trafficFilterHolder }
});
All demands to the server are executed as an http requests. Ther are two types of HTTP requests - GET and POST.
https://www.w3schools.com/tags/ref_httpmethods.asp
What you're describing is called GET request. With GET request the parameters are passed via the address bar. For making an http request you have two options.
The direct HTTP GET request.
For this you need simply open a new page with
window.location.href = 'http://your_site.com/file.php?name1=value1&name2=value2'
This will open a new page in your browser and pass a request with your parameters.
An Ajax HTTP GET request.
You have a lot of options here:
an old-fashion way with xmlHttpRequest object
a modern fetch API with promises
third-part libraries like jQuery.ajax etc.
AJAX request can send and receive information from the server (either in GET or POST request) without renewing the page. After that the result received can be managed with your javascript application however you want.
Hope, it makes more clear for you. You can search about all this technologies in the google. This is the way how to exchange data from front-end to back-end.
Try using ajax and pass that array and retrieve values at the PHP end.
var filters = encodeURI(JSON.stringify(trafficFilterHolder));
$.ajax({
type: "POST",
url: "test.php",
data: {data : filters},
cache: false,
success: function(){
alert("OK");
}
});
This may be a simple answer, but I'm using jQuery's $.ajax to call a PHP script. What I want to do is basically put that PHP script inside a function and call the PHP function from javascript.
<?php
if(isset($_POST['something'] {
//do something
}
?>
to this
<?php
function test() {
if(isset($_POST['something'] {
//do something.
}
}
?>
How would i call that function in javascript? Right now i'm just using $.ajax with the PHP file listed.
Use $.ajax to call a server context (or URL, or whatever) to invoke a particular 'action'. What you want is something like:
$.ajax({ url: '/my/site',
data: {action: 'test'},
type: 'post',
success: function(output) {
alert(output);
}
});
On the server side, the action POST parameter should be read and the corresponding value should point to the method to invoke, e.g.:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'test' : test();break;
case 'blah' : blah();break;
// ...etc...
}
}
I believe that's a simple incarnation of the Command pattern.
I developed a jQuery plugin that allows you to call any core PHP function or even user defined PHP functions as methods of the plugin: jquery.php
After including jquery and jquery.php in the head of our document and placing request_handler.php on our server we would start using the plugin in the manner described below.
For ease of use reference the function in a simple manner:
var P = $.fn.php;
Then initialize the plugin:
P('init',
{
// The path to our function request handler is absolutely required
'path': 'http://www.YourDomain.com/jqueryphp/request_handler.php',
// Synchronous requests are required for method chaining functionality
'async': false,
// List any user defined functions in the manner prescribed here
// There must be user defined functions with these same names in your PHP
'userFunctions': {
languageFunctions: 'someFunc1 someFunc2'
}
});
And now some usage scenarios:
// Suspend callback mode so we don't work with the DOM
P.callback(false);
// Both .end() and .data return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
Demonstrating PHP function chaining:
var data1 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).data();
var data2 = P.strtoupper("u,p,p,e,r,c,a,s,e").strstr([], "C,A,S,E").explode(",", [], 2).end();
console.log( data1, data2 );
Demonstrating sending a JSON block of PHP pseudo-code:
var data1 =
P.block({
$str: "Let's use PHP's file_get_contents()!",
$opts:
[
{
http: {
method: "GET",
header: "Accept-language: en\r\n" +
"Cookie: foo=bar\r\n"
}
}
],
$context:
{
stream_context_create: ['$opts']
},
$contents:
{
file_get_contents: ['http://www.github.com/', false, '$context']
},
$html:
{
htmlentities: ['$contents']
}
}).data();
console.log( data1 );
The backend configuration provides a whitelist so you can restrict which functions can be called. There are a few other patterns for working with PHP described by the plugin as well.
I would stick with normal approach to call the file directly, but if you really want to call a function, have a look at JSON-RPC (JSON Remote Procedure Call).
You basically send a JSON string in a specific format to the server, e.g.
{ "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}
which includes the function to call and the parameters of that function.
Of course the server has to know how to handle such requests.
Here is jQuery plugin for JSON-RPC and e.g. the Zend JSON Server as server implementation in PHP.
This might be overkill for a small project or less functions. Easiest way would be karim's answer. On the other hand, JSON-RPC is a standard.
You can't call a PHP function with Javascript, in the same way you can't call arbitrary PHP functions when you load a page (just think of the security implications).
If you need to wrap your code in a function for whatever reason, why don't you either put a function call under the function definition, eg:
function test() {
// function code
}
test();
Or, use a PHP include:
include 'functions.php'; // functions.php has the test function
test();
You are going to have to expose and endpoint (URL) in your system which will accept the POST request from the ajax call in jQuery.
Then, when processing that url from PHP, you would call your function and return the result in the appropriate format (JSON most likely, or XML if you prefer).
You may use my library that does that automatically, I've been improving it for the past 2 years http://phery-php-ajax.net
Phery::instance()->set(array(
'phpfunction' => function($data){
/* Do your thing */
return PheryResponse::factory(); // do your dom manipulation, return JSON, etc
}
))->process();
The javascript would be simple as
phery.remote('phpfunction');
You can pass all the dynamic javascript part to the server, with a query builder like chainable interface, and you may pass any type of data back to the PHP. For example, some functions that would take too much space in the javascript side, could be called in the server using this (in this example, mcrypt, that in javascript would be almost impossible to accomplish):
function mcrypt(variable, content, key){
phery.remote('mcrypt_encrypt', {'var': variable, 'content': content, 'key':key || false});
}
//would use it like (you may keep the key on the server, safer, unless it's encrypted for the user)
window.variable = '';
mcrypt('variable', 'This must be encoded and put inside variable', 'my key');
and in the server
Phery::instance()->set(array(
'mcrypt_encrypt' => function($data){
$r = new PheryResponse;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $data['key'] ? : 'my key', $data['content'], MCRYPT_MODE_ECB, $iv);
return $r->set_var($data['variable'], $encrypted);
// or call a callback with the data, $r->call($data['callback'], $encrypted);
}
))->process();
Now the variable will have the encrypted data.
Let's assume I have a post AJAX call and I want to put returned data into some HTML elements.
$.post(settings.url, function(data) {
$('#someElement').text(data.someData1);
$('#someElement2').text(data.someData2);
});
I'm a back-end developer and it's natural for me that I have to do server-side validation of any piece of data coming from user. Although it's the opposite situation, the code above feels a little bit wrong for me (not validated outside data). But on the other hand, I know what I'm returning from the server.
The question is if is it fine to trust that data returned from (also mine) back-end application will have expected structure, or should I validate somehow every data coming server?
Additional question is if there is some nice method to do such validation? Manual validating of existence of every piece of data seems to be a pain in the neck. Especially for more complex data structure.
Just during writing this question an idea came to my mind. I could use $.extend() just like it's commonly used for setting default options while writing modules/plugins. Something like:
$.post(settings.url, function(data) {
var trustedStructure = $.extend({
someData1: $('#someElement').text(),
someData2: $('#someElement2').text(),
}, data);
$('#someElement').text(trustedStructure .someData1);
$('#someElement2').text(trustedStructure .someData2);
});
That way I could have trusted data with additionally current data as default or any other if I want.
Edit:
Forgot to note. I'm talking about pure JSON data responses. No HTML etc included.
Generally you don't validate the response data, as you said before, the data is returned from your own back-end. What you really need to do is to ensure that you have a proper way to handle exceptions or errors with the information coming from the server.
If you're returning an exception from the server you should have a way in the client-side to figure out that if an error or not.
i.e. returning a specific code like a Rest API or having a JSON structure like this:
// Success
{
"error": false,
"data": {
...
}
}
// Exception
{
"error": true,
"message": "Username already taken",
"type": "warning"
}
If you always return a 200 OK status code:
$.ajax({
...
success: function(response) {
if (response.error) {
alert(response.error.message);
} else {
document.querySelector('#field').value = response.data.text;
}
}
});
The HTML Response Codes are useful when you use promises, you can return a 200 OK for the primary flow (success, done), and 4XX or 5XX if something unusual happen (fail):
$.ajax({
url: 'example.php',
...
})
.done(function(response) { alert(response.data); })
.fail(function(error) { alert(error.message); })
.always(function() { clearFields(); });
Does the data returned from your server contain DOM Elements?
If it doesn't and is a pure text return, you can use a textarea to parse incoming data like this:
var textArea = document.createElement('textarea');
textArea.innerHTML = data;
data = textArea.textContent;
Just try it out and let the server send some <p>, <img> or <script> Elements
I'm trying use jQuery's AJAX handling .load while passing several variables along with the request.
Normally, as a xmlhttp request GET, I would pass variables like so:
xmlhttp.open("GET","myfile.php?
var1="+data1+"&var2="+data2+"&var3="+data3+"&var4="+data4,true);
Using load, I can't get this to work (the request doesn't succed):
$('#txtHint').load("myfile.php?var1="+data1+"&var2="+data2+"&var3="+data3+"&var4="+data4 , null, function (){ });
In the space where it says "null" in the .load example, is the parameter for:
"data: This optional parameter represents a map of data that is sent with the request".
If I'm unserstanding that correctly, I believe I can use it to send my variables along with the request. However, I can't find information on how to format it.
How can I pass my variables along with the request using .load?
It looks like your method should work as a GET to myfile.php.
If you want to use the data parameter instead, then look at the official jQuery API docs for the .load() method (not to be confused with the .load() event handling method), where it says:
data
Type: PlainObject or String
A plain object or string that is sent to the server with the request.
So you can pass it as a string or as an object.
As a string (which you more or less already have):
$('#txtHint').load('myfile.php',
"var1="+data1+"&var2="+data2+"&var3="+data3+"&var4="+data4,
function() { }
);
As an object (note that this makes your request a POST):
$('#txtHint').load('myfile.php',
{
var1: data1,
var2: data2,
var3: data3,
var4: data4
},
function() { }
);
Most of the examples in the jQuery docs don't use the data parameter, but the last two examples at the very bottom of the page (as of typing this answer) shows some basic examples of using it in the object format.
I am creating a basic piece of functionality to allow users to send their location to a server which then queries a database and returns locations near to them. I am using the below jQuery .ajax wrapper to POST data to the server. This takes the form of a latlon point which is then used as the basis for a geosearch in MongoDB using nodejs and express on the backend. The results of the search are then intended to be returned to the client and rendered by the createMapListings function.
The /find page is initially rendered through a GET request to the database via mongodb separate from the below code. However subsequent to initial rendering, I then want to return results dependent on the location provided.
The POST method works fine and the location is posted to the server, with the search results being returned as I can print contents out through the console log.
However, I then want to render the results on the client-side. As mentioned, the results of the search render in the console, but when I attempt to pass through to the client, I can render the data itself (in the form of an array of objects) in the #output div, but the createMapListings function does not seem to catch the data.
In fact, the below function appears to be called but prints out over a thousand rows with the data that should be caught described as 'undefined'. I have tried to use res.render and res.redirect, but in the first case, the view renders in the div (which I suppose is expected) and the redirect fails.
The createMapListings function works fine when a simple GET request is made to the server, for example, for all objects in a collection, using ejs template. However, I think the issue here may be a combination of a POST request and then wanting to pass the results back to the AJAX request using the complete callback.
I apologise if the below code is somewhat obtuse. I’m definitely what you would call a beginner. I appreciate the above functionality may not possible so if there is a better way, I would of course be open to it (res.direct perhaps).
Here is the relevant client side script:
$(document).ready(function(){
$("#geolocate").click(function(){
navigator.geolocation.getCurrentPosition(geolocate, function(){
});
});
});
function geolocate(pos){
var latlonpt = [];
var x = pos.coords.latitude;
var y = pos.coords.longitude;
latlonpt.push(x);
latlonpt.push(y);
var obj = {
userlocation: latitudelongitudept
};
$.ajax({
url: "/find",
type: "POST",
contentType: "application/json",
processData: false,
data: JSON.stringify(obj),
complete: function (data) {
$('#output').html(data.responseText);
$('#infooutput').children().remove();
createMapListings(data.responseText);
}
});
};
function createMapListings(maps) {
for (var i = 0; i < maps.length; i++) {
var url = maps[i]._id;
var fullurl = "<a href='/show?id=" + url + "'>Route</a></div>";
var title = "<div>" + maps[i].title + " - " + fullurl +"";
$('#infooutput').append(title);
};
};
</script>
Here is the relevant route used in a basic express app to handle the post request made by the above .ajax wrapper.
exports.findbylocation = function(req, res) {
console.log(req.body.userlocation);
var userlocation = req.body.userlocation;
Map.ensureIndexes;
Map.find({loc :{ $near : userlocation }}, function(err, maps) {
if (err) {
console.log(err)
}
else {
var jmaps = JSON.stringify(maps);
console.log(jmaps);
res.send(jmaps);
}
});
};
By convention, the data variable name in an $.ajax callback signature refers to the parsed HTTP response body. Since your callback is on complete, we're actually passed the XMLHttpRequest used, by convention called xhr. You rightly grab the responseText property, but this needs parsing to be useful. So long as we take care over our Content-Type's and don't explicitly disable processData, jQuery will do the encoding/unencoding for us - we just deal with objects. This is a good thing, since the transport format isn't usually of any particular importance to the application logic. If we use res.json(maps) in place of res.send(jmaps), we can write our call more simply:
$.ajax({
url: '/find',
type: 'POST',
data: obj,
success: function(data) {},
error: function(xhr, text, err) {}
});
Here data is a Javascript object already parsed and ready to use. We also use a default application/x-www-form-urlencoded request rather than explicitly setting a contentType. This is the same as far as express is concerned: it will just be parsed by urlencoded instead of json.
Assuming you solved your client-sie problem.
As you are using express there is no need for JSON.stringfy,
you can use res.json(maps).