jReflectServer is a very small & lightweight java web-server / webservice-framework for creating pure java web applications. It can
Distributed under MIT license.
jReflectServer is based on proven components like HttpCore, FileUpload and jsoup.
You should not use jReflectServer alone if you expect your project to grow into a huge website that needs organized content! You can however use it as an addition to any existing system.
Download from sourceforge project page.
Learn using jReflectServer within minutes. This tutorial is split into two parts, a webservice part and an html part
Each page is generated by a java class implementing the WebPage interface (i.e. the generatePage method which has a request and a response parameter).
This is a first REST-based "hello world" example:
public class FirstPage implements WebPage { |
How to run this in standalone mode
Finally, direct your browser to http://localhost/MyPage.
See more REST code snippets here!
This is a first HTML-based "hello world" example:
public class FirstPage implements WebPage { |
Finally, direct your browser to http://localhost/MyPage.
Let's extend the example with some CSS:
wd.getStyle().append("h1 { color:red; font-size:48px; }"); |
See more HTML code snippets here.
JReflectServer can be used in embedded mode (programmatically) and in standalone mode (as shown before).
Create the following class JReflectTest.java as part of the same project which contains FirstPage.java:
public class JReflectTest { private final JReflectServer server = new JReflectServer("http://127.0.0.1:1234");
server.launchServer(this); |
The above code creates a new server instance on port 80. Again, direct your browser to http://localhost/MyPage.
So, where is the reference to FirstPage? There is none, but jReflectServer is able to scan the binary code source at runtime without prior knowledge of any classes implementing WebPage. You only need to pass one arbitrary instance which is part of the same code source, in the case above passing "this" to launchServer.
A request listener can be shut down using:
server.shutdownListener(80); |
Here's how you reference more jars using the embedded mode:
server.register("file:///home/some/folder/dynamicpages.jar"); |
No need for your implementation to be in the same file system. The following shows how to use a remote code base:
server.register("http://your.server.com/dynamicpages.jar"); |
The default update cycle time for jar files is 60 seconds. However, local jar files which are replaced should be reloaded immediately. You can change the update cycle time (in seconds) like this:
server.setDependencyUpdateCycle(30); |
Let's say you'd like to run jReflectServer on a dedicated web server but keep working on your hello world application without copying files after each build onto the server. Just run the command above from your dedicated server's shell but place the helloworld.jar on your home server (you can use jReflectServer as file server).
Try the following command: "java -jar jReflectServer_2.0.jar http://home.somedyndns.org/helloworld.jar -local:http://127.0.0.1:80,id_123 -update:30". jReflectServer checks by default every 30 seconds for modifications. When you update your jar, it will be reloaded automatically on the dedicated server.
jReflectServer transparently loads arbitrary files from the document root folder and from inside the code location (file system or jar). You may place java files side-by-side with html, js or any other files and reference these by simple relative file paths.
Example structure:
Deploying sources (java / class, js and html) as single jar will work perfectly fine when running it with jReflect.
Distributed request execution
As a reminder: No special code is needed to handle distributed code execution on remote server nodes. Using a distributed session which is synchronized with the "master" server, the code can be assumed to work on all nodes.
To create a server cluster, just start a master server node. Such a node is a normal server node which get's a unique server ID so that the slave server nodes can register at the master server:
JReflectServer master = new JReflectServer("http://127.0.0.1:1234", "id_ee0c4d16"); master.lauchServer(this); |
The ID can be any unique string, e.g. a UUID. Now, create a number of slave server nodes and register at the master node using the IP address and the ID:
JReflectServer slave1 = new JReflectServer("http://127.0.0.1:1235", "id_slave_01_abc"); slave1.setMasterHost("http://127.0.0.1:1234", "id_3ebd9e13"); slave1.lauchServer(this); JReflectServer slave2 = new JReflectServer("http://127.0.0.1:1236", "id_slave_02_xyz"); slave2.setMasterHost("http://127.0.0.1:1234", "id_3ebd9e13"); slave2.lauchServer(this); |
That's pretty much it. Note the different port numbers used in this example for testing 3 servers on the same machine (1235 and 1236). Any generatePage implementation will now be executed randomly on the master or on one of the slave nodes.
You can see the results be printing out the server ID on the request:
public void generatePage(JReflectServer server, WebRequest request, WebResponse response) throws Exception { |
Besides programmatically lauching multiple server instances, you can do this also in standalone mode from the command-line, e.g.:
See a distributed code execution example here.
Some more code snippets...
Be nice to low bandwidth connections. Setting the gzip flag will compress the http response:
response.setGzip(true); |
Note that the response will only be compressed if the request header field "Accept-Encoding" contains the entry "gzip".
Any exception thrown in the generatePage method will produce an Internal Server Error (500) as response. If the exception is a WebPageException the response will contain a stack trace which can be viewed in the browser. If stack traces should always be visible, the best practice is to catch all exceptions and rethrow a WebPageException:
public void generatePage(JReflectServer server, WebRequest request, WebResponse response) throws Exception { |
SSL/TLS can be enabled by providing an SSLContext instance to the jReflectServer.
SSLContext sslContext = SSLContext.getInstance("Default"); |
jReflectServer depends on the following components (all integrated):
jsoup | MIT License |
HttpCore | Apache License 2 |
FileUpload | Apache License 2 |
servlet-api (as part of tomcat core) | Apache License 2 |