2016-05-18 4 views
1

Используя следующие зависимости (Gradle):Создание бизнес-домена объекты доступны Джерси Servlet контексте во встроенном сервере Jetty

  • org.glassfish.jersey.containers:jersey-container-servlet:2.22.2

  • org.eclipse.jetty:jetty-servlet:9.3.2.v20150730

у меня есть встроенный Jetty сервер, с контейнером сервлетов Джерси ... что-то вроде этого ...

package mypkg.rest.jersey; 

import org.eclipse.jetty.server.Server; 
import org.eclipse.jetty.servlet.ServletContextHandler; 
import org.eclipse.jetty.servlet.ServletHolder; 
import org.glassfish.jersey.server.ServerProperties; 
import org.glassfish.jersey.servlet.ServletContainer; 
import se.transmode.tnm.alarm.api.AlarmRetrieval; 
import mypkg.rest.RestServer; 
import mypkg.rest.jersey.serviceImpl.ModelAdapter; 

public class JerseyBasedRestServer implements RestServer { 

public static final int INITIALIZE_ON_USE = 0; 
private Server server; 
private final ServletContextHandler context; 
private final ServletHolder servlet; 
private final ModelAdapter modelAdapter; 

public JerseyBasedRestServer(BusinessObjects businessObjects) { 
    this.modelAdapter = new ModelAdapter(businessObjects); //I want this instance to somehow be available for my ServletContainer to use. 

    context = new ServletContextHandler(ServletContextHandler.SESSIONS); 
    servlet = context.addServlet(ServletContainer.class, "/*"); 
    servlet.setInitOrder(INITIALIZE_ON_USE); 
    servlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "mypackage.jersey.generated.api.service"); 
    servlet.setInitParameter(ServerProperties.MEDIA_TYPE_MAPPINGS, "json : application/json"); 
    context.setContextPath("/"); 
} 

private void startServlet() { 
    try { 
     servlet.start(); 
     servlet.initialize(); 
    } catch (Exception e) { 
     log.error("Failed to initialize servlet. {}", e.getMessage()); 
    } 
} 

@Override 
public void init(int port) { 
    server = new Server(port); 
    server.setHandler(context); 
    try { 
     server.start(); 
     server.join(); 
     startServlet(); 
    } catch (Exception e) { 
     log.error("Failed to start jetty server for rest interface"); 
    } finally { 
     server.destroy(); 
    } 
} 

Джерси Контейнер будет выполнять код сервера и модель, сгенерированный с использованием Сваггера кода поколение инструмента

https://github.com/swagger-api/swagger-codegen#getting-started

который обеспечивает сформированную модель, JacksonJsonProvider, и RestApi класса:

package mypackage.jersey.generated.api.service 

Path("/") 
public class RestApi { 
    private final RestApiService delegate = new RestApiServiceImpl(); //Integration point of the generated code 

    @GET 
    @Path("/list/") 
    @Consumes({ "application/json" }) 
    @Produces({ "application/json" }) 
    public Response retrieveAlarmList(@Context SecurityContext securityContext) throws NotFoundException { 
    return delegate.retrieveAlarmList(securityContext); 
    } 
} 

Чтобы интегрировать сгенерированный код, нам осталось реализовать RestApiServiceImpl.

Задача ModelAdapter заключается в преобразовании наших бизнес-объектов в созданную модель покоя.

Таким образом, вопрос, как я могу сделать экземпляр адаптера наших бизнес-объекты, в данном случае ModelAdapter, который находится вне контекста контекста сервлета Джерси, доступно для RestApi класса, а точнее RestApiServiceImpl?

Я как бы понял, прочитав за последние 24 часа, что мне нужно использовать какую-либо инъекцию контекстной зависимости через Jetty, Jersey или какую-либо другую библиотеку (кажется, кажется, что Weld), и попробовали различные комбинации @Inject, @Context и т. Д., Но пришли к выводу, что я понятия не имею, что я на самом деле делаю ... Я даже не уверен, что правильно понимаю ситуацию, чтобы правильно рассказать о моем вопросе.

Дополнительная информация может быть предоставлена ​​по запросу.

Любая помощь приветствуется.

EDIT: добавил ссылку здесь, чтобы https://github.com/englishbobster/JersetAndJetty

используя @peeskillets предложения, но до сих пор не работает.

ответ

2

Первое, что вам нужно сделать для DI-работы, это AbstractBinder. Здесь вы сможете сделать ваши объекты доступными для инъекций.

class Binder extends AbstractBinder { 
    @Override 
    protected void configure() { 
     bind(modelAdapter).to(ModelAdapter.class); 
    } 
} 

Тогда вам необходимо зарегистрировать связующее вещество с Джерси. Самый простой способ - зарегистрироваться в Джерси ResourceConfig. В вашем случае вы его не используете. Вы настраиваете все в «web.xml». Для этого вы должны взглянуть на this post.

Если вы хотите изменить конфигурацию, чтобы использовать ResourceConfig, который лично я предпочел бы использовать, вы можете сделать это

package com.some.pkg; 

public class JerseyConfig extends ResourceConfig { 
    public JerseyConfig() { 
     packages("mypackage.jersey.generated.api.service"); 
     property(ServerProperties.MEDIA_TYPE_MAPPINGS, "json : application/json"); 
     register(new Binder()); 
    } 
} 

Затем настроить его с Jetty, вы можете сделать

servlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, 
         "com.some.pkg.JerseyConfig"); 

Теперь вы можете избавиться от двух других параметров init-param, поскольку вы настраиваете его внутри ResourceConfig.

Другим способом, без инициализации-Params, это сделать

ResourceConfig config = new JerseyConfig(); 
ServletHolder jerseyServlet = new ServletHolder(ServletContainer(config)); 
context.addServlet(jerseyServlet, "/*"); 

Посмотреть полный пример последнего фрагмента кода, here.

Теперь вы можете просто впрыснуть ModelAdapter почти везде в пределах Джерси

В поле

@Inject 
private ModelAdapter adapter; 

Или в застройщик

@Inject 
public RestApi(ModelAdapter adapter) { 
    this.adapter = adapter; 
} 

или метод параметра

@GET 
public Response get(@Context ModelAdapter adapter) {} 
+0

ОК спасибо за ответ. Я пробовал что-то подобное этому во время моих экспериментов. Я только что попробовал свой рецепт выше, создав Binder и конфигурацию ресурсов, а затем используя инъекцию в поле, но при использовании моего ModelAdapter я все еще получаю исключение нулевого указателя. Каков наилучший способ увидеть контекст в отладчике (если вообще возможно)? – Englishbob

+0

btw Я никогда не использовал web.xml для конфигурации, (страх перед XML) и пытался делать все программно. – Englishbob

+1

Он должен вставить в «RestApi» просто отлично. Если вы пытаетесь внедрить его в службу, то вы не сможете создать экземпляр службы самостоятельно. Вам необходимо: 1) Привязать услугу с помощью связующего, и 2) _Inject_ сервис в RestApi, не создавать экземпляр –

 Смежные вопросы

  • Нет связанных вопросов^_^