Equinox OSGi应用嵌入Jersey框架搭建REST服务

原文地址:https://www.cnblogs.com/kira2will/p/5040264.html

一、环境

eclipse版本:eclipse-luna 4.4

jre版本:1.8

二、Equinox OSGi应用嵌入Jersey框架搭建REST服务

1.新建插件工程HelloWebOSGI

  a.

b.

c.

   d.在新建的工程中新建文件夹lib,其中放入附件中的jar包(见文末),全部添加到工程Build Path中。

 

2.配置运行环境

  a.配置引入包、依赖插件

   b.选择Run->Run Configuration,new一个环境

 

保留图中TargetPlatform中的16个Bundle。

  c.在Run Configuration中设置参数

 

友情提示:如果有其他异常请查看提示信息,利用 http://www.aolsearch.com/ 查询提示信息(英文),如果发现http://stackoverflow.com/这个网站有相同提问,基本就知道答案近在咫尺了。

              比如笔者遇到的问题:Root exception:java.lang.IllegalStateException: Workbench has not been created yet.

              解决方法就是在http://stackoverflow.com/questions/13773582/workbench-has-not-been-created-yet-error-in-eclipse-plugin-programming中找到的。

   d.在MANIFEST.MF(META-INF)文件中将lib文件夹中的包都引入如下图中。

 

 3.添加代码

 

Activator_sample.java

package helloworldosgi;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.logging.Logger;

import javax.servlet.ServletException;

import org.glassfish.jersey.servlet.ServletContainer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.util.tracker.ServiceTracker;

/*
 * BundleActivator:让你能够捕捉到bundle的start和stop事件,并对这两个事件作出自定义的反应。
 */
public class Activator_sample implements BundleActivator {    
    private BundleContext bc;
    @SuppressWarnings("rawtypes")
    private ServiceTracker tracker;
    private HttpService httpService = null;
    private static final Logger logger = Logger.getLogger(Activator.class.getName());

    /**
     * URL前缀
     */
    public static final String CONTEXT_PATH = "/rest/json";
    
    /*
     * BundleContext:一个bundle在框架中的执行时上下文,这个上下文提供了和框架进行交互的方法。
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public synchronized void start(BundleContext bundleContext)    throws Exception {
        this.bc = bundleContext;    
        logger.info("STARTING HTTP SERVICE BUNDLE");
    
        this.tracker = new ServiceTracker(this.bc, HttpService.class.getName(),    null) {
            @Override
            public Object addingService(ServiceReference serviceRef) {
                httpService = (HttpService) super.addingService(serviceRef);
                registerServlets();
                return httpService;
            }
    
            @Override
            public void removedService(ServiceReference ref, Object service) {
                if (httpService == service) {
                    unregisterServlets();
                    httpService = null;
                }
                super.removedService(ref, service);
            }
        };
    
        this.tracker.open();
    
        logger.info("HTTP SERVICE BUNDLE STARTED");
    }

    /*
     * BundleContext:一个bundle在框架中的执行时上下文,这个上下文提供了和框架进行交互的方法。
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     */
    @Override
    public synchronized void stop(BundleContext bundleContext) throws Exception {
        this.tracker.close();
    }
    
    private void registerServlets() {
        try {
            rawRegisterServlets();
        } catch (InterruptedException | NamespaceException | ServletException ie) {
            throw new RuntimeException(ie);
        }
    }

    private void rawRegisterServlets() throws ServletException,    NamespaceException, InterruptedException {
        logger.info("JERSEY BUNDLE: REGISTERING SERVLETS");
        logger.info("JERSEY BUNDLE: HTTP SERVICE = " + httpService.toString());
    
        // TODO - temporary workaround
        // This is a workaround related to issue JERSEY-2093; grizzly (1.9.5)
        // needs to have the correct context
        // classloader set
        ClassLoader myClassLoader = getClass().getClassLoader();
        ClassLoader originalContextClassLoader = Thread.currentThread()
                .getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(myClassLoader);
            httpService.registerServlet(CONTEXT_PATH, new ServletContainer(),
                    getJerseyServletParams(), null);
            httpService.registerResources(CONTEXT_PATH + "/hello", "/webroot", null);//前面必须带“/”,后面不一定
        } finally {
            Thread.currentThread().setContextClassLoader(
                    originalContextClassLoader);
        }
        // END of workaround - after grizzly updated to the recent version, only
        // the inner call from try block will remain:
        // httpService.registerServlet("/jersey-http-service", new
        // ServletContainer(), getJerseyServletParams(), null);
    
        sendAdminEvent();
        logger.info("JERSEY BUNDLE: SERVLETS REGISTERED");
    }

    @SuppressWarnings("serial")
    private void sendAdminEvent() {
        @SuppressWarnings("rawtypes")
        ServiceReference eaRef = bc.getServiceReference(EventAdmin.class
                .getName());
        if (eaRef != null) {
            @SuppressWarnings("unchecked")
            EventAdmin ea = (EventAdmin) bc.getService(eaRef);
            ea.sendEvent(new Event("jersey/test/DEPLOYED",
                    new HashMap<String, String>() {
                        {
                            put("context-path", "/");
                        }
                    }));
            bc.ungetService(eaRef);
        }
    }

    private void unregisterServlets() {
        if (this.httpService != null) {
            logger.info("JERSEY BUNDLE: UNREGISTERING SERVLETS");
            httpService.unregister(CONTEXT_PATH);
            logger.info("JERSEY BUNDLE: SERVLETS UNREGISTERED");
        }
    }

    private Dictionary<String, String> getJerseyServletParams() {
        Dictionary<String, String> jerseyServletParams = new Hashtable<>();
        jerseyServletParams.put("javax.ws.rs.Application",
                RestApplication.class.getName());
        logger.info("kira2will" + RestApplication.class.getName());
        return jerseyServletParams;
    }
    

}

StatusService.java

package helloworldosgi;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import data.Node;

@Path("/status")
public class StatusService {

    private static final Logger logger = Logger.getLogger(StatusService.class.getName());
    
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Node getStatus(){
        
        List<Node> nodes = new ArrayList<Node>();
        Node node = new Node("001", "60800","192.168.1.1","0","92","92","chizhou","50ms","hw");
        Node nothingNode = new Node("null","null","null","null","null","null","null","null","null");
        //nodes.add(node);
        nodes.add(node);
        logger.info(node.getName());
        return node;
    }
    
    @Path("/{id}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Node getID(@PathParam("id") int id){        
        List<Node> nodes = new ArrayList<Node>();
    
        nodes.add(new Node("null","null","null","null","null","null","null","null","null"));
        nodes.add(new Node("001", "60600","192.168.1.1","0","92","92","tonglin","50ms","hw"));
        nodes.add(new Node("002", "60600","192.168.1.1","0","92","92","tonglin","50ms","hw"));
        nodes.add(new Node("003", "60600","192.168.1.1","0","92","92","tonglin","50ms","hw"));
        nodes.add(new Node("004", "60600","192.168.1.1","0","92","92","tonglin","50ms","hw"));
        nodes.add(new Node("005", "60600","192.168.1.1","0","92","92","tonglin","50ms","hw"));        
        
        int defaultIndex = 0;
        if ( (id < 1) || (id > nodes.size() - 1) ){
            logger.info(nodes.get(defaultIndex).getId());
            return nodes.get(defaultIndex);
        }
        else{
            logger.info(nodes.get(id).getId());
            return nodes.get(id);
        }        
    }
}

RestApplication.java

package helloworldosgi;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;

public class RestApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> result = new HashSet<Class<?>>();

        result.add(JacksonJsonProvider.class);

        result.add(StatusService.class);

        return result;
    }
}

Node.java

package data;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Node {
    
    private String id;
    private String name;
    private String admin_ip;
    private String admin_status;
    private String longitude;
    private String latitude;
    private String location;
    private String latency;
    private String vendor_name;
    
    public Node(String id,
                String name,
                String admin_ip,
                String admin_status,
                String longitude,
                String latitude,
                String location,
                String latency,
                String vendor_name
                ){
        this.id = id;
        this.name = name;
        this.admin_ip = admin_ip;
        this.admin_status = admin_status;
        this.longitude = longitude;
        this.latitude = latitude;
        this.location = location;
        this.latency = latency;
        this.vendor_name = vendor_name;
    }
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAdmin_ip() {
        return admin_ip;
    }

    public void setAdmin_ip(String admin_ip) {
        this.admin_ip = admin_ip;
    }

    public String getAdmin_status() {
        return admin_status;
    }

    public void setAdmin_status(String admin_status) {
        this.admin_status = admin_status;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getLatency() {
        return latency;
    }

    public void setLatency(String latency) {
        this.latency = latency;
    }

    public String getVendor_name() {
        return vendor_name;
    }

    public void setVendor_name(String vendor_name) {
        this.vendor_name = vendor_name;
    }    
}

4.浏览器中输入 http://localhost:8080/rest/json/status 即可访问public Node getStatus() 返回值。

或者输入 http://localhost:8080/rest/json/status/2 即可访问public Node getID(@PathParam("id") int id)返回值。

关于@Path @Get @PathParam 参考 http://www.docin.com/p-317614298.html 第七页。

http://download.csdn.net/detail/kira_will/9729055

 原文地址:https://www.cnblogs.com/kira2will/p/5040264.html

原文地址:https://www.cnblogs.com/dyh004/p/10648003.html