2017-06-12 62 views
0

我想从一个servlet集成XLLoop并尝试通过HTTP协议运行。下面是我的代码:如何将Xlloop集成到JAVA Web服务器中?

XlloopServlet.java

@WebServlet(value = "/FunctionServer", name = "FunctionServer", asyncSupported = true) 
public class XlloopServlet extends FunctionServlet { 

private static final long serialVersionUID = -3845895326255874126L; 

@Override 
public void init(final ServletConfig config) throws ServletException { 
    // Create a function information handler to register our functions 
    FunctionInformationHandler infoHandler = new FunctionInformationHandler(); 

    // Create a reflection function handler and add the required methods 
    FunctionHandler handler = new FunctionHandler(); 

    infoHandler.add(handler.getFunctions()); 

    // Set the handlers 
    CompositeFunctionHandler compositeHandler = new CompositeFunctionHandler(); 
    compositeHandler.add(handler); 
    compositeHandler.add(infoHandler); 

    // Setting the function handler in the parent servlet 
    setHandler(compositeHandler); 
} 

和我FunctionHandler类注册功能:

public class FunctionHandler implements IFunctionHandler, FunctionProvider { 
private ReflectFunctionHandler rfh; 
public FunctionHandler() { 
    // Create a reflection function handler and add the Math methods 
    rfh = new ReflectFunctionHandler(); 
    rfh.addMethods("Math.", Math.class); 
    rfh.addMethods("Math.", Maths.class); 
    rfh.addMethods("CSV.", CSV.class); 
    rfh.addMethods("Reflect.", Reflect.class); 
} 

@Override 
public XLoper execute(IFunctionContext arg0, String arg1, XLoper[] arg2) throws RequestException { 
    return rfh.execute(arg0, arg1, arg2); 
} 

@Override 
public boolean hasFunction(String arg0) { 
    return rfh.hasFunction(arg0); 
} 

@Override 
public FunctionInformation[] getFunctions() { 
    return rfh.getFunctions(); 
} 

public ReflectFunctionHandler getReflectFunctionHandler() { 
    return rfh; 
} 
} 

我XLLoop ini文件是如下:

protocol=http 
url=http://localhost:8080/MyApp/FunctionServer 

现在,当我尝试从我的excel中调用一个函数时,我会在servlet类中接收一个调用并且永远执行的东西,但函数没有得到执行的Excel文件。

任何人有任何想法如何将XLLoop插件整合到像tomcat这样的网络服务器上?

回答

1

我刚刚使用JAX-RS和Spring的一些实现。我使用REST端点为正在运行的服务填充xlloop.ini文件和正确的服务器主机/端口,然后将zip文件中的xlsb,xll和ini文件打包,以供客户端下载。目前并不特别漂亮,但web.xml和Startup片段在下面。

我还没有花时间的事情是内存管理。如果很多用户加载大量数据,我需要定期清理那些数据,因此请注意空闲的会话线程!

的web.xml

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 
<listener> 
    <listener-class>com.myapp.web.excel.XLLoopStartup</listener-class> 
</listener> 

XLLoopStartup.java

public class XLLoopStartup implements ServletContextListener { 
    public static XLLoopStartup    INSTANCE; 
    private FunctionServer     fs; 

    @Inject 
    private SomeInjectionThing    usefulSpringStuff; 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     INSTANCE = this; 

     // Initialize my Spring stuff 
     if (sce != null){ 
      WebApplicationContextUtils// 
       .getRequiredWebApplicationContext(sce.getServletContext())// 
       .getAutowireCapableBeanFactory()// 
       .autowireBean(this); 
     } 

     Executors.newSingleThreadExecutor().execute(new Runnable() { 

      @Override 
      public void run() { 
       registerConverters(); 

       fs = new FunctionServer(Integer.parseInt(System.getProperty("port.tomcat.xlloop", "10606"))); 

       ReflectFunctionHandler rfh = new ReflectFunctionHandler(); 
       rfh.addMethods(ExcelTrades.CATEGORY, ExcelTrades.class); 
       rfh.addMethods(ExcelUtils.CATEGORY, ExcelUtils.class); 
       rfh.addMethods(ExcelPositions.CATEGORY, ExcelPositions.class); 
       rfh.addMethods(ExcelProducts.CATEGORY, ExcelProducts.class); 

       // Create a function information handler to register our functions 
       FunctionInformationHandler firh = new FunctionInformationHandler(); 
       firh.add(rfh.getFunctions()); 

       // Set the handlers 
       CompositeFunctionHandler cfh = new CompositeFunctionHandler(); 
       cfh.add(rfh); 
       cfh.add(firh); 
       DebugFunctionHandler debugFunctionHandler = new DebugFunctionHandler(cfh); 
       fs.setFunctionHandler(new SecureFunctionHandler(debugFunctionHandler)); 
       try { 
        fs.run(); 
       } 
       catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    // For quick testing 
    public static void main(String[] args) { 
     new XLLoopStartup().contextInitialized(null); 
    } 

    // Function classes can statically access this instance and get spring things from it 
    public SomeInjectionThing getThing() { 
     return usefulSpringStuff; 
    } 

} 

ExcelService.java

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.StringWriter; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipOutputStream; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.core.UriInfo; 

import org.apache.commons.io.IOUtils; 

import io.swagger.annotations.Api; 

@Api("excel") 
@Path("/excel") 
public class ExcelService { 

    @Context 
    UriInfo uri; 

    @GET 
    @Path("/download") 
    @Produces({ MediaType.APPLICATION_OCTET_STREAM }) 
    public Response download() { 
     StringWriter sw = new StringWriter(); 

     // Create an INI file. We should probably store all default settings in a file and just add the server info to 
     // it. 
     sw.write("server="); 
     sw.write(uri.getBaseUri().getHost()); 
     sw.write(":"); 
     sw.write(System.getProperty("port.tomcat.xlloop", "10605")); 
     String inifile = sw.toString(); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try (ZipOutputStream zos = new ZipOutputStream(baos)) { 

      // Add the ini file to the zip 
      ZipEntry entry = new ZipEntry("xlloop.ini"); 
      zos.putNextEntry(entry); 
      zos.write(inifile.getBytes()); 
      zos.closeEntry(); 

      // Add the Excel files 
      writeFileFromClasspath(zos, "xlloop.xll"); 
      // This is my custom Excel macro sheet with other useful functions for user authentication etc. 
      writeFileFromClasspath(zos, "xlloop.xlsb"); 
     } 
     catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 

     return Response.ok(new ByteArrayInputStream(baos.toByteArray())) 
       .header("Content-Disposition", "attachment; filename=xlloop.zip").build(); 
    } 

    private void writeFileFromClasspath(ZipOutputStream zos, String filename) throws IOException { 
     ZipEntry xlFileEntry = new ZipEntry(filename); 
     zos.putNextEntry(xlFileEntry); 
     zos.write(IOUtils.toByteArray(ExcelService.class.getClassLoader().getResourceAsStream(filename))); 
     zos.closeEntry(); 
    } 
} 
相关问题