keskiviikko 10. huhtikuuta 2013

Tutorial 1. Part 19 - making java class into a web service



Web service parts
Let’s add web service annotations. You can do this with a wizard
Start by pressing righ button down over the Java class ShellScriptWrapper. A pop-up menu appear. Select Create Web Service from the list of choices.




Next we’ll give the service a name.



Select  SOAP 1.2 binding and Document/Literal as message format.



Methods to expose

No additional classes





You could set policies immediately here (like whether authentication is needed and what flavor should be used)








The wizard creates a folder called Web Content and places a file called web.xml there. Web.xml is the deployment descriptor telling what parts the web application is made of.
Also it adds Java-WS annotations to our class.  The class definition gets:
@WebService(portName = "ScriptWrapperSoap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class ShellScriptWrapper {
And our execute method gets an annotation and becomes:
    @WebMethod
public int execute(

You can optionally add
    @WebResult(name = "exitCode") to the execute method. This will name the return value so that automated tools that you can use for testing will show that as the name for the return from the service.
You can optionally add @WebParam directive to name the parameters.





The final version is like this:
package com.blogger.soanen;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
@WebService(name = "ShellScriptWrapper", serviceName = "ShellScriptWrapperService", portName = "ShellScriptWrapperSoap12HttpPort")
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class ScriptWrapper {
    public final int IO_ERROR = -1;
    public final int SCRIPT_INTERRUPTED = -2;
    public final int NULL_COMMAND_ELEMENT = -3;
    public final int EMPTY_COMMAND = -4;
    public final int NOT_ALLOWED = -5;
    public final int UNKNOWN_SCRIPT = -6;
    private Map<String, Script> scripts = new HashMap<String, Script>();

    public ScriptWrapper() {
        super();
        scripts.put("a.bat", new Script("C:\\TEMP\\a.bat", "C:\\TEMP"));
    }
    @WebMethod
    @WebResult(name = "exitCode")
    public int executeScript( @WebParam(name = "script")
        String script , @WebParam(name = "arg")
        String... args ) {
        Script s = scripts.get(script);
        if (s != null) {

            List<String> command = new ArrayList<String>(1 + args.length);
            command.add(s.getScriptPath());
            for (String arg : args)
                command.add(arg);
            ProcessBuilder pb = new ProcessBuilder(command);
            Process p;
            pb.directory(new File(s.getScriptDir()));
            try {
                p = pb.start();
                return p.waitFor();
            } catch (IOException e) {
                e.printStackTrace();
                return IO_ERROR;
            } catch (InterruptedException e) {
                return SCRIPT_INTERRUPTED;
            } catch (NullPointerException e) {
                return NULL_COMMAND_ELEMENT;
            } catch (IndexOutOfBoundsException e) {
                return EMPTY_COMMAND;
            } catch (SecurityException e) {
                return NOT_ALLOWED;
            }
        } else
            return UNKNOWN_SCRIPT;
    }
    public static void main(String[] args) {
        try {
            ScriptWrapper scriptWrapper = new ScriptWrapper();
            int ret;
            //ret = scriptWrapper.executeScript("cmd.exe", "c:\\temp", "/c", "a.bat");
            ret = scriptWrapper.executeScript("a.bat", "");
            System.out.println("return value = " + ret);
        } catch (Exception e1) {
            System.out.println(e1);
        }
    }
}
}
There is loads of stuff missing from the current implementation. A more thorough version should capture the ouput of the scripts and relay it back to the called. You may decide to do some postprocessing of captured text unless it is well formatted, this could lead to significant additions to you wrapper.
Current version also executes only one script and then returns. It’s fairly common to have a pre-script validating conditions, actual functional script and finally a post-processing script checking everything went well. You might want to make the wrapper execute all scripts in the list that match the script name to remove the amount of calls the client needs to make etc.


Ei kommentteja:

Lähetä kommentti