I'm connecting to a webserver with a specific JavaScript. (Using HttpURLConnection atm)
What i need is a connection that makes it possible to manipulate a JavaScript function.
Afterwards i want to run the whole JavaScript again.
I want the following function always to return "new FlashSocketBackend()"
function createBackend() {
if (flashSocketsWork) {
return new FlashSocketBackend()
} else {
return new COMETBackend()
}
}
Do i have to use HtmlUnit for this?
Whats the easiest way to connect, manipulate and re-run the script?
Thanks.
With HtmlUnit you indeed can do it.
Even though you can not manipulate an existing JS function, you can however execute what JavaScript code you wish on an existing page.
Example:
WebClient htmlunit = new WebClient();
HtmlPage page = htmlunit.getPage("http://www.google.com");
page = page.executeJavaScript("<JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
more:
http://www.aviyehuda.com/2011/05/htmlunit-a-quick-introduction/
Your best shot is probably to use Rhino — an open-source implementation of JavaScript written entirely in Java. Loading your page with a window.location and hopefully running your JavaScript function. I read sometime before Bringing the Browser to the Server and seemed possible.
Related
I want to run JavaScript code at the server side. I want to manipulate result returned by JavaScript inside my Java code. How can it be done?
The start is clearly to look into rhino.
I think you will find this 3 links very useful
JavaScript EE, Part 1: Run JavaScript files on the server side
JavaScript EE, Part 2: Call remote JavaScript functions with Ajax
JavaScript EE, Part 3: Use Java scripting API with JSP
You can also have a look to helma
Helma is a server-side Javascript environment and web application framework for fast and efficient scripting and serving of your websites and Internet applications.
Helma is written in Java and employs Javascript for its server-side scripting environment ...
The other answers are correct that if you want to execute Javascript on the server side, you'd need to evaluate it in the context of a JS runtime.
However, I'm not convinced that this is exactly what you're asking. I think there may be a chance that you want to run some "typical" JS functionality that relates to how the page is displayed on the client's machine or interacted with on the client - and that will not be possible to run on the server side.
As a concrete examples:
If you want to run some kind of algorithm in JS without porting it to Java - say, you have some opaque Javascript code that generates a particular sequence given a seed - this would work fine if you run it on Rhino on the server.
If you want to invoke a Javascript function while creating the page, rather than while it's running - say, to get the user's colour depth/screen resolution and change how the page is generated - then this will not be possible from the server, as there is no client at this point to query.
Broadly speaking, any Javascript that involves document or navigator or even any elements of the page itself, is likely to fall into the latter category.
If you really need to get information about the client environment in order to control how the page is rendered, this must be extracted from the client on the previous page, and encoded into the request (as query parameters or form data). These parameters can then be read directly on the server and used to control the output.
Remember that when your code is running on the server side, you're creating a page (ultimately a bunch of HTML, CSS and JS) that will be sent to the client once it's done - at this point there is no client yet and so you can't interact with them.
Apologies if I've got the wrong end of the stick on this one, but this type of question is typically asked by people who haven't grasped the client/server separation.
You need a JS runtime inside of a Java runtime. One way to do this is Rhino
You execute the JavaScript with Rhino, a JavaScript library for Java.
You can use RHINO or NASHORN.
public class RhinoApp {
private String simpleAdd = "var z=9; z*=9";
public void runJavaScript() {
Context jsCx = Context.enter();
Context.getCurrentContext().setOptimizationLevel(-1);
ScriptableObject scope = jsCx.initStandardObjects();
Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
Context.exit();
System.out.println(result);
}
This example should clearly state how to load, evaluate and execute a Javascript function in Java:
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
URI source_js = JavascriptExecutor.class.getResource("/file.js").toURI();
String source_text = Files.readAllLines(Paths.get(source_js)).stream().collect(Collectors.joining("\n"));
engine.eval(source_text);
Invocable inv = (Invocable) engine;
Object returnValue = inv.invokeFunction("functionJsName", "functionJsParameter");
System.out.println(returnValue.toString());
I create a basic GWT (Google Web Toolkit) Ajax application, and now I'm trying to create snapshots to the crawlers read the page.
I create a Servlet to response the crawlers, using HtmlUnit.
My application runs perfectly when I'm on a browser. But when in HtmlUnit, it throws a lot of errors about the special chars I have in the HTML. But these chars are content, and I wouldn't like to replace it with the special codes, once it's currently working, just because of the HtmlUnit. (at least I should check before if I'm using HtmlUnit correctly )
I think HtmlUnit should read the charset information of the page and render it as a browser, once it's the objective of the project I think.
I haven't found good information about this problem. Is this an HtmlUnit limitation? Do I need to change all the content of my website to use this java library to take snapshots?
Here's my code:
if ((queryString != null) && (queryString.contains("_escaped_fragment_"))) {
// ok its the crawler
// rewrite the URL back to the original #! version
// remember to unescape any %XX characters
url = URLDecoder.decode(url, "UTF-8");
String ajaxURL = url.replace("?_escaped_fragment_=", "#!");
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
HtmlPage page = webClient.getPage(ajaxURL);
// important! Give the headless browser enough time to execute JavaScript
// The exact time to wait may depend on your application.
webClient.waitForBackgroundJavaScript(3000);
// return the snapshot
response.getWriter().write(page.asXml());
The problem was XML confliting with the HTML. #ColinAlworth comments helped me.
I followed Google example, and there was not working.
To it work, you need to remove XML tags and let just the HTML be responded, changing the line:
// return the snapshot
response.getWriter().write(page.asXml());
to
response.getWriter().write(page.asXml().replaceFirst("<\\?.*>",""));
Now it's rendering.
But although it is being rendered, the CSS is ot working, and the DOM is not updated (GWT updates page title when page opens). HTMLUnit throwed a lot of errors about CSS, and I'm using twitter bootstrap without any changes. Apparently, HtmlUnit project have a lot of bugs, good for small tests, but not to parse complex (or even simple) HTMLs.
I want to know how to call a java method from HTML (I Use HTML5) using java script. I tried using Applets but this didnt work. I have to take the value of a drop down box in the html file and take it to a java method to process it.
What you are looking for is AJAX. It's extremely easy to do with a library such as jQuery
$.get('your/servlet').done(function(data) {
// data is the data returned by the request
});
Jabsorb implements this: http://code.google.com/p/jabsorb/
You will want to do this with a request to a servlet. Like ThiefMaster said, Ajax is a good way to go
Here's a quick article to get you started: http://javapapers.com/ajax/getting-started-with-ajax-using-java/
I want to run JavaScript code at the server side. I want to manipulate result returned by JavaScript inside my Java code. How can it be done?
The start is clearly to look into rhino.
I think you will find this 3 links very useful
JavaScript EE, Part 1: Run JavaScript files on the server side
JavaScript EE, Part 2: Call remote JavaScript functions with Ajax
JavaScript EE, Part 3: Use Java scripting API with JSP
You can also have a look to helma
Helma is a server-side Javascript environment and web application framework for fast and efficient scripting and serving of your websites and Internet applications.
Helma is written in Java and employs Javascript for its server-side scripting environment ...
The other answers are correct that if you want to execute Javascript on the server side, you'd need to evaluate it in the context of a JS runtime.
However, I'm not convinced that this is exactly what you're asking. I think there may be a chance that you want to run some "typical" JS functionality that relates to how the page is displayed on the client's machine or interacted with on the client - and that will not be possible to run on the server side.
As a concrete examples:
If you want to run some kind of algorithm in JS without porting it to Java - say, you have some opaque Javascript code that generates a particular sequence given a seed - this would work fine if you run it on Rhino on the server.
If you want to invoke a Javascript function while creating the page, rather than while it's running - say, to get the user's colour depth/screen resolution and change how the page is generated - then this will not be possible from the server, as there is no client at this point to query.
Broadly speaking, any Javascript that involves document or navigator or even any elements of the page itself, is likely to fall into the latter category.
If you really need to get information about the client environment in order to control how the page is rendered, this must be extracted from the client on the previous page, and encoded into the request (as query parameters or form data). These parameters can then be read directly on the server and used to control the output.
Remember that when your code is running on the server side, you're creating a page (ultimately a bunch of HTML, CSS and JS) that will be sent to the client once it's done - at this point there is no client yet and so you can't interact with them.
Apologies if I've got the wrong end of the stick on this one, but this type of question is typically asked by people who haven't grasped the client/server separation.
You need a JS runtime inside of a Java runtime. One way to do this is Rhino
You execute the JavaScript with Rhino, a JavaScript library for Java.
You can use RHINO or NASHORN.
public class RhinoApp {
private String simpleAdd = "var z=9; z*=9";
public void runJavaScript() {
Context jsCx = Context.enter();
Context.getCurrentContext().setOptimizationLevel(-1);
ScriptableObject scope = jsCx.initStandardObjects();
Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
Context.exit();
System.out.println(result);
}
This example should clearly state how to load, evaluate and execute a Javascript function in Java:
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
URI source_js = JavascriptExecutor.class.getResource("/file.js").toURI();
String source_text = Files.readAllLines(Paths.get(source_js)).stream().collect(Collectors.joining("\n"));
engine.eval(source_text);
Invocable inv = (Invocable) engine;
Object returnValue = inv.invokeFunction("functionJsName", "functionJsParameter");
System.out.println(returnValue.toString());
I'm using htmlunit to test some pages and I'd like to know how can I execute some javascript code in the context of the current page. I'm aware that the docs say I'd better emulate the behavior of a user on a page, but it isn't working this way :( (I have a div which has an onclick property, I call its click method but nothing happens). So I've made some googling and tried:
JavaScriptEngine jse = webClient.getJavaScriptEngine();
jse.execute(page, what here?);
Seems like I have to instantiate the script first, but I've found no info on how to do it (right). Could someone share a code snippet showing how to make webclient instance execute the needed code?
You need to call executeJavaScript() on the page, not on webClient.
Example:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
webClient.setJavaScriptEnabled(true);
HtmlPage page = webClient.getPage("http://www.google.com/ncr");
ScriptResult scriptResult = page.executeJavaScript("document.title");
System.out.println(scriptResult.getJavaScriptResult());
prints "Google". (I'm sure you'll have some more exciting code to put in there.)
I don't know the JavaScriptEngine you're quoting and maybe it's not the answer you want, but this sounds like a perfect case for Selenium IDE.
Selenium IDE is a Firefox add-on that records clicks, typing, and other actions to make a test, which you can play back in the browser.
In TestPlan using the HTMLUnit backend the google example is:
GotoURL http://www.google.com/ncr
set %Title% as evalJavaScript document.title
Notice %Title%