How to use a java socket in tapestry5?
How do I implement a java socket in tapestry5? What I want to do is create a socket which I can send an XmlHttpRequest over, through a piece of javascript code.
function sendPost(url, postdata, callback) {
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null) {
alert ("Browser does not support HTTP Request")
return
}
xmlHttp.onreadystatechange=ca开发者_运维百科llback
xmlHttp.open("POST",url,true)
xmlHttp.send(postdata);
}
Where the URL is the socket i have just created.
So you want to do an AJAX request from your client code to the server, recieve a response and process it in some way? You will not need sockets. Instead, use Tapestry's built-in AJAX functionality.
If you're loading additional content inside your page via Javascript, chances are you will not need to write any code at all. Be sure you have read the AJAX section from the Tapestry docs, and you understand what a Zone is and how it works.
Here's a basic example. Template:
<div id="myZone" t:type="Zone" t:id="myZone">
... [Initial content, if any] ...
</div>
<a t:type="ActionLink" t:id="updateContent" t:zone="myZone">Update</a>
And class:
@Inject
private Zone myZone;
@Inject
private Request request;
@OnEvent(component = "updateContent")
Object updateContent() {
... [your code] ....
if (this.request.isXHR()) {
return this.myZone.getBody();
} else {
return this;
}
}
Tapestry will do everything else, like registering the proper event listener on the link and inserting the updated content in the proper place. The if (this.request.isXHR())
makes sure your page will degrade gracefully for clients without JavaScript enabled.
If you'd like to do something else entirely, like returning a JSON object and processing it with your own JavaScript code, you can return any of these JSON classes from your event handler.
Also, if you want to write your own client-side code, be sure to use the built-in, cross-browser AJAX functionality of Prototype, which ships with Tapestry.
Edit based on comment:
You won't be able to access a different server (host + port) through AJAX because of the same origin policy. You could, however, proxy the call through your Tapestry app. I've modified my code to illustrate this (assuming the thing listening on port 2112 is an HTTP server, otherwise change as needed):
@OnEvent(component = "updateContent")
Object updateContent() throws IOException {
final URL url = new URL("http://localhost:2112");
final HttpURLConnection con = url.openConnection();
final String content;
InputSteam input = null;
try {
input = con.getInputStream();
content = IOUtils.toString(input);
} finally {
IOUtils.closeQuietly(input);
}
return new StreamResponse() {
@Override
public String getContentType() {
return "text/javascript";
}
@Override
public InputStream getStream() throws IOException {
return new ByteArrayInputStream(content.getBytes("UTF-8"));
}
@Override
public void prepareResponse(Response response) {
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
}
}
}
Use of Sockets is independent of your webapp view framework - you would do it pretty much the same way regardless of how the view is coded. The only thing that changes is once you've implemented your code that uses sockets, is how that's invoked.
I used tapestry with spring, and so injecting services into the spring context is the most natural approach.
The services
subpackage in tapestry is mostly for creating implementations that plug into tapestry, like encoders, property conduits, and binding factories. So whether you use this or not depends upon what you are trying to achieve.
For example, if you are creating a component that reads from a socket, and renders the data read in, then you can create that as a regular component, in the components
subpackage.
The XmlHttpRequest will just do a web server request which can be handled perfectly well by whatever you use to run Tapestry in. There is no need to open sockets and stuff.
Just define a route in your wep application to accept the XmlHttpRequest and have a handler, servlet, controller, ... collect the necessary data, transform it to xml and send it to the Javascript component.
I found an example here
精彩评论