Предоставленные ответы не помогли мне в моем случае, когда я пытаюсь запустить свой сервер в eclipse, и он дает мне класс, не найденный исключение [дубликат]

Что вы должны знать о this

this (иначе говоря, «контекст») - это специальное ключевое слово внутри каждой функции, и его значение зависит только от , как была вызвана функция, а не как / когда / где она была определена. Лексические области не затрагиваются, как и другие переменные. Вот несколько примеров:

function foo() {
    console.log(this);
}

// normal function call
foo(); // `this` will refer to `window`

// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`

// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`

Чтобы узнать больше о this, просмотрите документацию MDN .


Как сделать обратитесь к правильному this

Не используйте this

Фактически вы не хотите иметь доступ к this в частности, но объект, на который он ссылается на . Вот почему простое решение - просто создать новую переменную, которая также относится к этому объекту. Переменная может иметь любое имя, но общие - self и that.

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function() {
        alert(self.data);
    });
}

Поскольку self является нормальной переменной, она подчиняется лексическим правилам области и доступна внутри обратного вызова. Это также имеет то преимущество, что вы можете получить доступ к значению this самого обратного вызова.

Явно установить this обратного вызова - часть 1

Возможно, у вас есть не контролируйте значение this, потому что его значение устанавливается автоматически, но на самом деле это не так.

Каждая функция имеет метод .bind [docs] , который возвращает новую функцию с this, привязанную к значению. Функция имеет то же поведение, что и тот, который вы назвали .bind, только то, что this было установлено вами. Независимо от того, как и когда эта функция вызывается, this всегда будет ссылаться на переданное значение.

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // parenthesis are not necessary
        alert(this.data);             // but might improve readability
    }).bind(this); // <- here we are calling `.bind()` 
    transport.on('data', boundFunction);
}

В этом случае мы привязываем обратный вызов this к значению MyConstructor 's this.

Примечание. При связывании контекста для jQuery вместо этого используйте jQuery.proxy [docs] . Причина этого заключается в том, что вам не нужно сохранять ссылку на функцию при отмене обратного вызова события. jQuery обрабатывает это внутренне.

ECMAScript 6: Используйте функции стрелок

В ECMAScript 6 представлены функции стрелок , которые можно рассматривать как лямбда-функции. У них нет собственной привязки this. Вместо этого this просматривается в области видимости как обычная переменная. Это означает, что вам не нужно называть .bind. Это не единственное особое поведение, которое у них есть. Дополнительную информацию см. В документации MDN.

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', () => alert(this.data));
}

Установите this обратного вызова - часть 2

Некоторые функции / методы, которые принимают обратные вызовы, также принимают значение, к которому должен обращаться обратный вызов this. Это в основном то же самое, что и привязывать его самостоятельно, но функция / метод делает это за вас. Array#map [docs] - такой метод. Его подпись такова:

array.map(callback[, thisArg])

Первый аргумент - это обратный вызов, а второй аргумент - значение this. Вот надуманный пример:

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
    return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument

Примечание. Можно ли передать значение для this, как правило, упоминается в документации этой функции / метода. Например, метод $.ajax jQuery [docs] описывает параметр, называемый context:

Этот объект станет контекстом всех обратных вызовов, связанных с Ajax.


Общая проблема: использование объектных методов в качестве обработчиков обратных вызовов / событий

Еще одно распространенное проявление этой проблемы - когда объектный метод используется как обработчик обратного вызова / события , Функции являются первоклассными гражданами в JavaScript, а термин «метод» - просто разговорный термин для функции, которая является значением свойства объекта. Но эта функция не имеет конкретной ссылки на ее «содержащий» объект.

Рассмотрим следующий пример:

function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = function() {
    console.log(this.data);
};

Функция this.method назначается как обработчик события click , но если щелкнуть document.body, зарегистрированное значение будет undefined, потому что внутри обработчика события this ссылается на document.body, а не на экземпляр Foo. Как уже упоминалось в начале, то, что относится к [49], зависит от того, как называется функция, а не от того, как она определена. Если код выглядит следующим образом, может быть более очевидно, что функция не имеет неявной ссылки на объект:

function method() {
    console.log(this.data);
}


function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = method;

Решение такое же, как указано выше: если доступно, используйте .bind явно привязать this к определенному значению

document.body.onclick = this.method.bind(this);

или явно вызвать функцию как «метод» объекта, используя анонимную функцию в качестве обработчика обратного вызова / события и назначить object (this) к другой переменной:

var self = this;
document.body.onclick = function() {
    self.method();
};

или использовать функцию стрелки:

document.body.onclick = () => this.method();
39
задан ROMANIA_engineer 16 December 2015 в 08:16
поделиться

9 ответов

Проблема:

java.lang.ClassNotFoundException: org.glassfish.jersey.servlet.ServletContainer

указывает, что вы пытаетесь использовать сервлет Джерси 2.x, но вы поставляете лиги Джерси 1.x.

Для Джерси 1 .x вы должны сделать это следующим образом:

<servlet>
  <servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
  com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>sample.hello.resources</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Jersey REST Service</servlet-name>
  <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Для получения дополнительной информации проверьте документацию Jersey 1.x . Если вы вместо этого хотите использовать Jersey 2.x, то вам придется предоставить Jersey 2.x libs. В проекте, основанном на maven, вы можете использовать следующее:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.xx</version>
</dependency>
<!-- if you are using Jersey client specific features without the server side -->
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.xx</version>
</dependency>

Для Jersey 2.x вам не нужно ничего настраивать в web.xml, достаточно предоставить класс, подобный этому :

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest")
public class ApplicationConfig extends Application {

}

Для получения дополнительной информации проверьте документацию Jersey .

См. также:

77
ответ дан Community 20 August 2018 в 14:34
поделиться
  • 1
    А что, если вы хотите использовать Jersey 2.x? – DuKes0mE 29 June 2014 в 18:15
  • 2
    Если вы используете Джерси 1 или 2, вам все равно нужны зависимости (хотя старые - com.sun ...). Вы только показываете web.xml для Джерси 1. – Roger 10 May 2015 в 17:09
  • 3
    Для Джерси 2 класс сервлета должен быть <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> в web.xml в соответствии с документами, но я не уверен, что должен быть param-name. jersey.java.net/documentation/latest/deployment.html . Обновление Я думаю, что это jersey.config.server.provider.packages. – Hack-R 17 October 2016 в 20:22
  • 4
    Я использую Jersey 2.26 и Tomcat 8.0 с Jdk 8. Но я все еще получаю ошибку, я включил все банки в путь сборки. Я не использую Maven, пожалуйста, дайте некоторое решение, не используя Maven. – Amit Shil 17 December 2017 в 05:48

У меня была та же проблема с eclipse, WA-решение заключалось в том, чтобы скопировать библиотеки в WEB-INF / lib

0
ответ дан 15412s 20 August 2018 в 14:34
поделиться

Если вы используете функцию Джерси 2.x, используйте следующую зависимость:

<dependency>
   <groupId>org.glassfish.jersey.containers</groupId>
   <artifactId>jersey-container-servlet-core</artifactId>
   <version>2.XX</version>
</dependency>  

Где XX может быть любая конкретная версия, которую вы ищете. Контейнеры Джерси .

10
ответ дан agpt 20 August 2018 в 14:34
поделиться

На самом деле jersey-container-servlet использует зависимость jersey-container-servlet-core. Но если вы используете maven, это не имеет большого значения. Если вы просто определите использование jersey-container-servlet, оно также автоматически загрузит зависимость.

Но для тех, кто добавляет файлы jar в свой проект вручную (т. Е. Без maven). Важно знать, что вы на самом деле нужны оба файла jar. Класс org.glassfish.jersey.servlet.ServletContainer фактически является частью основной зависимости.

1
ответ дан bvdb 20 August 2018 в 14:34
поделиться

Предположим, вы используете Jersey 2.25.1, это сработало для меня - я использую веб-контейнер Apache Tomcat:

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.25.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.25.1</version>
    </dependency>

NB: Замените версию версией, используемой вами

0
ответ дан Chris J Kikoti 20 August 2018 в 14:34
поделиться

Это проблема установки eclipse, а не проблема с Джерси.

Из этого потока ClassNotFoundException: org.glassfish.jersey.servlet.ServletContainer

Щелкните правой кнопкой мыши проект проекта eclipse. Свойства -> Развертывание сборки -> Добавить -> Записи пути сборки Java -> Зависимости подгонки -> Готово.

Итак, Eclipse не использовал зависимости Gradle при запуске Apache.

19
ответ дан chrki 20 August 2018 в 14:34
поделиться

Я согласен с принятым ответом. Но для меня проблема была не в этом, вместо этого мне пришлось изменить имя моего сервлета-класса: -

<servlet-class>org.glassfish.jersey.servlet.ServletContainer.class</servlet-class> 

To:

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

Итак, удаление .class отлично работал в моем случае. Надеюсь, это поможет кому-то!

1
ответ дан Nerdy 20 August 2018 в 14:34
поделиться

Ниже код работает для меня в файле web.xml

<servlet>
    <servlet-name>WebService</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.example.demo.webservice</param-value>
        //Package
    </init-param>
    <init-param>
        <param-name>unit:WidgetPU</param-name>
        <param-value>persistence/widget</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>WebService</servlet-name>
    <url-pattern>/webservices/*</url-pattern>
</servlet-mapping>
3
ответ дан ROMANIA_engineer 20 August 2018 в 14:34
поделиться
1
ответ дан Jordi M. 31 October 2018 в 10:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: