I have a java program that has some number of classes. Three methods taken input A and give output B. I need to make these methods available as a web service so that I can ask something like http://test.com/method?input=A and the result B is returned. I don't want to re-write my existing code. Is there something which is available such as a web service framework for JAVA that can allow me to create a web service interface for these three methods. What is the easiest way?
I have ran into many acronyms and other stuff during my research such as dynamic project, JAVA EE, Glassfish etc... What can implement my requirement? Thanks!
You will probably need some sort of web framework -- Glassfish is one example. Basically, your application is not built to receive web requests, so you need some sort of container (e.g. a Servlet Container like Tomcat http://en.wikipedia.org/wiki/Web_container ).
I think "restlet" is a little servlet container that might suit your needs.
Check it out: http://www.restlet.org/
If you're running on a Java EE 6 server, you can use JAX-RS: http://docs.oracle.com/javaee/6/tutorial/doc/gilik.html
The easiest way to do quick Java services I've found is Restlet.
You can use their tutorials to get a webserver up and running like literally 20 minutes from scratch. The Restlet below should work right out of the box as a skeleton framework. You'll replace the call of String b = ... of course, and replace it with your own library.
public class Main extends Application {
public static void main(String[] args) {
Main main = new Main();
main.start();
}
private void start() {
Component c = new Component();
c.getServers().add(Protocol.HTTP, 80);
Application app = new Main();
c.getDefaultHost().attach(app);
c.start();
}
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/method/{input}", new Restlet(getContext()) {
public void handle(Request request, Response response) {
String a = request.getAttributes().get("input").toString();
String b = MyLibraries.compute(a);
response.setEntity(b, MediaType.TEXT_HTML);
}
});
return router;
}
}
Related
I have a problem with my REST webservice I want to run asynchronously. The example shows, what I want to do. The main problem is that the web service is not accepting a new request until the old finished. I am using Wildfly 10 as my application server and its RESTeasy implementation.
WebApplication.java
#ApplicationPath("rest")
public class WebApplication extends Application
{
public WebApplication ()
{
super();
}
}
TestService.java
#Path("test")
public class TestService
{
#Inject
private TestBean bean;
#GET
#Produces(MediaType.APPLICATION_JSON)
public void getDateTime(#Suspended final AsyncResponse response)
{
CompletableFuture.supplyAsync(() -> response.resume(bean.getResult()))
.exceptionally((ex) -> (response.resume(ex)));
}
}
TestBean.java
#Stateless
public class TestBean
{
public TestTO getResult()
{
Logger.getLogger(Thread.currentThread().getName()).log(Level.INFO, "Entering REST service");
for (long l = 0; l < Long.MAX_VALUE; l++)
{
// just for simulating a veeeery heavy operation
}
return new TestTO();
}
}
The TestTO is just a simple POJO, so nothing special in there. I cant imagine whats wrong. I searched in google to have a look at different approaches but nothing worked. Something I tried, too, just for testing:
I placed the loop after the response.resume() call and a new request was accepted without leaving the previous one (used simple logging statements to debug).
So... What is blocking a second request? I really dont get it, or am I missing something ridiculous?
Thanks in advance!
Okay, I figured it out.
I didn't write a client appliation which performs the requests simultaneous, instead I used Firefox to quickly see the output. I opened 2 tabs and called the URL for the webservice. Later I did exactly the same with Microsoft Edge and ... its working! The exmaple is working to 100%.
I dont know why... maybe because Edge is spawning a complete new process per tab and Firefoy doesnt? Never mind, next time I use SoupUI to test webservices.
I am sorry for the stupid question. If I had worked correctly, I had seen the issue.
I need to make an service in jboss and access it through JNDI on the client side.
I have been playing around a bit with JNDI and made something like this on the client side:
import javax.naming.*;
public class App {
public static void main(String[] args) throws NamingException {
App app = new App();
app.setSysProp();
app.setObject();
app.getObject();
}
public void setSysProp() {
System.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
}
public void setObject() throws NamingException {
Context context = new InitialContext();
MyObject obj = new MyObject();
obj.setName("NameOfMyObject");
context.bind("obj", obj);
}
public void getObject() throws NamingException {
Context context = new InitialContext();
MyObject obj = (MyObject) context.lookup("obj");
System.out.println(obj.getName());
}
}
This only binds and object to jndi on the client side and later retrieves it.
Now what i want is to bind a similar object on the server side (Jboss 4.2.3) and through it make some operations on the server. How can this be done? Ive read that something named RMI should be used in this case but what exactly is that and how to use it?
Ive read that something named RMI should be used in this case but what exactly is that and how to use it?
RMI is the Java standar API for Remote Method Invocation. It allows you execute a method on a object that reside in other Java Virtual Machine. Take in mind that you don't need a application server like JBoss to communicate with a remote java object. This link provides a simple tutorial.(notice that JBoss or any other app server is not mentioned)
I need to make an service in jboss and access it through JNDI on the client side.
This is a different thing. Although, JBoss (as a Java EE specification compliant server) use RMI extensively, you don't need understand how this API works. What you need is to create a server side component called EJB which allows you to have a service running on a server.
How can this be done?
There are hundred of tutorials about how to implement a basic EJB. Choose one compatible with your JBoss version due to some implementation details often change from one version to another.
You will also find that EJB specification has been evolving. With JBoss 4.2.3 and Java 5 you can start with EJB 3.0 which is easier than the previous one (2.1)
I'm new to java web services.
Now i'm trying to create a web service client to access a WSDL based web service. So using eclipse i generated the required client stubs/Binding stubs/Port/Port proxy/ServiceLocator etc.
According to my understanding next step is to create a class with the main method to invoke it. Can anyone help me to write that piece of code or at least some links to refer?
EDITED
Thank you so much for the hint #pavan-kumar. Finally i come up with following code and it works. Thanks again.
package clients;
import requiredClasses;
public class TestClient {
public static void main(String args[]) throws Exception
{
TestPortProxy tProxy = new TestPortProxy();
RequestEntity rEntity = new RequestEntity();
rEntity.setAttribute1(100);
rEntity.setAttribute2("value1");
tProxy.webServiceAction(rEntity);
}
}
You already generated required client files with the WSDL ,so next create your own class in that create an object for proxy class which is generated by WSDL, by using that object you can call web service methods in your application.
The question might seem stupid/trivial and might be, but I simply cannot understand how to achieve my goal. (Sorry if the title is misguiding, couldn't think of a better one)
I have a webpage on a App Engine server which uses GWT. I got client code and server code. The client code can call RPC methods without any problem (my problem has nothing to do with the "gwt-client" at all).
I got the following classes:
//MyClassService.java - client package
#RemoteServiceRelativePath("myService")
public interface MyClassService extends RemoteService{
public doSomething();
}
//MyClassServiceAsync.java - client package
public interface MyClassServiceAsync{
public void doSomething(AsyncCallback<Void> callback);
}
//MyClassServiceImpl.java - server package
public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
#Override
public void doSomething()
{
//does something
}
}
A scenario and what I want to do:
I've got a remote client, in other words, a client who's not connecting through the page via the "GWT-interface", it's a client who's simply making GET, POST requests to a path on the server (from elsewhere). This remote client is not "using" GWT at all. The client is connecting through an HttpServlet, inside this servlet I want to reuse the RPC mechanics so that i don't have to rewrite the interfaces, who are on the client side and using client-dependent code (the implementation is already server-side).
To reuse the existing methods on the server-side I could create an instance of MyClassServiceImpl.java and just use those. BUT as you can see above, they are implemented as synchronous methods, since GWT-RPC automatically makes the calls asyncronous when using the GWT-RPC.
How would i go about to reuse the MyClassServiceImpl on the server-side and also get them as asynchronous?
Also if I'm wrong with the approach I'm taking, please suggest some other solution. For example, one solution might be for the remote client to directly communicate with the RemoteServiceServlet instead of creating a HttpServlet which the client connects through, but I don't know if that's possible (and if it is, please tell me how)!
Thank you!
EDIT (thanks to some answers below I got some insight and will try to improve my question):
The server-side implementation of the methods is SYNCHRONOUS. Meaning they will block until results a returned. When invoking these method from the gwt-client code, they are 'automatically' made ASYNCHRONOUS one can call them by doing the following:
MyClassServiceAsync = (MyClassServiceAsync) GWT.create(MyClassService.class);
ServiceDefTarget serviceDef = (ServiceDefTarget) service;
serviceDef.setServiceEntryPoint(GWT.getModuleBaseURL() + "myService");
service.doSomething(new AsyncCallback<Void>() {
#Override
public void onSuccess(Void result) {
//do something when we know server has finished doing stuff
}
#Override
public void onFailure(Throwable caught) {
}
});
As you can see from the above code, there is support for the doSomething method to take an AsyncCallback, without even having the implementation for it. This is what I wanted on the server-side so i didn't have to use threads or create a new implementation for "async-usage". Sorry if I was unclear!
1) Any client can call MyClassServiceImpl.doSomething() with the current configuration. MyClassServiceImpl is a servlet and properly exposed. In order to achieve communication this way, the client must be able to "speak" the GWT dialect for data transportation. Google may provide you with libraries implementing this. I haven't used any, so I cannot make suggestions.
An example, proof-of-concept setup: Check the network communications with Firebug to get an idea of what is going on. Then try calling the service with curl.
2) If you do not want to use the GWT dialect, you can easily expose the same service as REST (JSON) or web services (SOAP). There are plenty of libraries, e.g. for the REST case RestEasy and Jersey. You do not mention any server-side frameworks (Spring? Guice? CDI?), so the example will be simplistic.
I'd suggest implementing your business method in a class independent of transportation method:
public class MyBusinessLogic {
public void doSomething() {
...
}
}
Then, the transport implementations use this business logic class, adding only transport-specific stuff (e.g. annotations):
GWT:
public class MyClassServiceImpl extends RemoteServiceServlet implements MyClassService{
#Override
public void doSomething() {
MyBusinessLogic bean = ... // get it from IoC, new, whatever
bean.doSomething();
}
}
JAX-RS:
#Path("myService")
public class MyResource {
#GET
public void doSomething() {
MyBusinessLogic bean = ... // get it from IoC, new, whatever
bean.doSomething();
}
}
So the transport endpoints are just shells for the real functionality, implemented in one place, the class MyBusinessLogic.
Is this a real example? Your method takes no arguments and returns no data.
Anyhow you can create a new servlet and invoke it via normal HTTP request. The servlet then just invokes the target method:
public class MyNewServlet extends HttpServlet{
protected void doGet(HttpServletRequest request, HttpServletResponse response){
MyBusinessLogic bean = ... // get it from IoC, new, whatever
bean.doSomething();
}
}
I am following a little tutorial for JAX-WS mkyong - jax-ws
I have published this little example with the following code on my Windows 7 machine.
But how can I update or remove this webservice?
public class HelloWorldPublisher {
public static void main(String[] args) {
Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
}
}
Remove : If you want to remove the web service, just use the Endpoint.stop() (read here) methods for stopping it accept the requests.
Update : Just change the code in the HelloWorldImpl class. It will automaticaly call the newly updated code.
Endpoint.publish() simply tells the server that the requests in the given URL should be processed using HelloWorldImpl