Добавьте CrossOriginFilter в dropwizard с помощью guice

Я довольно новичок в dropwizard и guice. Когда я локально нажимаю на свой API из кода ajax, я получаю следующую ошибку в консоли моего браузера. В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, Origin 'null' не имеет доступа.

После изучения ошибки многие люди предлагают добавить CrossORiginFilter в мой код dropwizard. это делается через env.addFilter Но я пытаюсь использовать Guice. вот мой основной класс

public static void main( String[] args ) throws Exception
{
    new TListService().run( args );
}

@Override
public void initialize( Bootstrap<TListServiceConfiguration> bootstrap )
{
    bootstrap.setName( "tlist" );
    bootstrap.addBundle( GuiceBundle.< TListServiceConfiguration > newBuilder().addModule( new JpaPersistModule( this.getClass().getPackage().getName() ) ).setConfigClass( TListServiceConfiguration.class )
            .enableAutoConfig( this.getClass().getPackage().getName() ).build() );
}

@Override
public void run( TListServiceConfiguration config, Environment env ) throws Exception
{        
}

и вот мой код ajax:

$(document).ready(function() {
    $('#btnSend').click(function(){
        var apiUrl = $('#txtServer').val() + $("#selectApi").val();
        console.log("URL: " + apiUrl);
        var postData = JSON.parse($('#textData').val());
        console.log(postData);
        console.log(JSON.stringify(postData));
        $.ajax({
            url: apiUrl,
            async: false,
            type: 'POST',
            dataType:"json",
            contentType:"application/json; charset=UTF-8",
            data: JSON.stringify(postData),
        })
        .done(function(data) {
            console.log("success");
            console.log(data);
        })
        .fail(function() {
            console.error("Error");
        })
        .always(function() {
            console.log("complete");
        });
    });     
});

person Saeid Farivar    schedule 29.03.2014    source источник
comment
Я не вижу ничего плохого в том, чтобы просто использовать Environment таким образом. Это не сильно экономит с точки зрения внедрения через Guice и не снижает возможности тестирования.   -  person sean    schedule 31.03.2014
comment
Спасибо за ваш комментарий. Я думаю, вы правы, в конце концов я сделал это, используя среду, и она работает нормально. хотя я все еще пытаюсь заставить его работать с помощью google-guice.   -  person Saeid Farivar    schedule 31.03.2014
comment
Я думаю, что одним из способов было бы написать оболочку для самого Application, чтобы вы могли @Inject его использовать во вспомогательном методе или, по крайней мере, что-то в этом роде.   -  person sean    schedule 31.03.2014


Ответы (2)


У нас была та же проблема, мы хотели использовать guice для внедрения фильтров, полученное решение модифицировало GuiceBudle для внедрения фильтров accpet, в нашем случае для этого мы все еще носили @WebFilter, иначе вам придется использовать Environment.

В классе AutoConfig вы можете создать метод addFilters, который будет использовать библиотеку для поиска отражений всех классов, аннотированных с помощью @WebFilter, примерно так:

public void addFilters(Environment env, Injector injector) {
    Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(WebFilter.class);
    for (Class<?> annotated : annotatedClasses) {
        env.addFilter(injector.getInstance(annotated), annotated.getAnnotation(WebFilter.class).urlPatterns()[0];
    }
}

или вы можете позже добавить фильтр в метод запуска:

@Override
public void run( TListServiceConfiguration config, Environment env ) throws Exception {      
    env.addFilter(Filter.class, "urlPatterns");
}
person user3323968    schedule 31.03.2014
comment
Не могли бы вы объяснить больше или, возможно, добавить код? Я очень новичок в dropwizard и guice. - person Saeid Farivar; 01.04.2014
comment
Спасибо за код. Я нашел другой пример, и он сработал для меня. это было чем-то похоже на ваш подход. - person Saeid Farivar; 22.04.2014

Сначала создайте фильтр, разрешающий междоменные запросы.

public class CrossDomainFilter implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

            HttpServletResponse res = (HttpServletResponse) response;

            res.setHeader("Access-Control-Allow-Origin", "*");
            res.setHeader("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
            res.setHeader("Access-Control-Allow-Credentials", "true");
            res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
            res.setHeader("Access-Control-Max-Age", "1209600");

            chain.doFilter(request, response);
        }
}

Затем добавьте сопоставление в метод run() вашего класса службы.

env.getApplicationContext().addFilter(CrossDomainFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR));

Надеюсь это поможет.

person Prashant    schedule 22.04.2014
comment
Спасибо за ответ. хотя ваш ответ работает, я хотел использовать его с умом. вот почему я собираюсь выбрать другой ответ в качестве ответа на этот вопрос. - person Saeid Farivar; 22.04.2014