Java: на нестатическую переменную нельзя сослаться от статической Ошибки контекста

Я только что столкнулся с той же проблемой и пришел к выводу, что другие ответы немного сложнее, чем они должны быть, поэтому вот мой подход для тех, кто не хочет полагаться на большее количество библиотек или декораторов:

Запрос CORS фактически состоит из двух HTTP-запросов. Запрос предварительной проверки, а затем фактический запрос, который выполняется только в случае успешной предварительной проверки.

Предварительный запрос

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

Я написал функцию Python для построения этого ответа, используя функцию make_response из модуля flask.

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add("Access-Control-Allow-Headers", "*")
    response.headers.add("Access-Control-Allow-Methods", "*")
    return response

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

Этот ответ убедит ваш браузер (Chrome) идти вперед и выполнить фактический запрос.

Фактический запрос

При обслуживании фактического запроса вы должны добавить один заголовок CORS - в противном случае браузер не вернет ответ на вызывающий код JavaScript. Вместо этого запрос потерпит неудачу на стороне клиента. Пример с jsonify

response = jsonify({"order_id": 123, "status": "shipped"}
response.headers.add("Access-Control-Allow-Origin", "*")
return response

Я также написал функцию для этого.

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response

позволяя вам вернуть однострочник.

Окончательный код

from flask import Flask, request, jsonify, make_response
from models import OrderModel

flask_app = Flask(__name__)

@flask_app.route("/api/orders", methods=["POST", "OPTIONS"])
def api_create_order():
    if request.method == "OPTIONS": # CORS preflight
        return _build_cors_prelight_response()
    elif request.method == "POST": # The actual request following the preflight
        order = OrderModel.create(...) # Whatever.
        return _corsify_actual_response(jsonify(order.to_dict()))
    else
        raise RuntimeError("Wierd - don't know how to handle method {}".format(request.method))

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add('Access-Control-Allow-Headers', "*")
    response.headers.add('Access-Control-Allow-Methods', "*")
    return response

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response
8
задан marcog 5 January 2011 в 14:02
поделиться

5 ответов

Нет, на самом деле, вы должны объявить свое поле con2 static:

private static java.sql.Connection con2 = null;

Edit: Исправление, на самом деле этого будет недостаточно, вы получите ту же проблему, потому что ваш метод getConnection2Url также не статический. Лучшим решением может быть следующее изменение:

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

 public void run() {
     con2 = java.sql.DriverManager.getConnection(getConnectionUrl2());
 }
10
ответ дан 3 November 2019 в 12:50
поделиться

Ваш метод main () является статическим, но он ссылается на два нестатических члена: con2 и getConnectionUrl2 (). Вам нужно сделать одно из трех:

1) Сделать con2 и getConnectionUrl2 () статическими.

2) Внутри main () создать экземпляр класса testconnect и получить доступ к con2 и getConnectionUrl2 () от него.

3) Выделите другой класс для хранения con2 и getConnectionUrl2 (), чтобы в testconnect был только main. По-прежнему необходимо будет создать экземпляр другого класса и вызвать методы из него.

Вариант №3 - лучший вариант. Наихудшее - №1.

Но вы не можете получить доступ к нестатическим членам из статического метода.

5
ответ дан 3 November 2019 в 12:50
поделиться

В Java есть два типа переменных

a)
Уровень класса (статический):
Они по одному на каждый класс. Допустим, у вас есть класс ученика и определено имя как статическая переменная. Теперь независимо от того, сколько объектов ученика вы создадите, все они будут иметь одинаковое имя.

Уровень объекта:
Они принадлежат каждому объекту. Если имя нестатическое, тогда у всех учащихся могут быть разные имена.

b)
Уровень класса:
Эти переменные инициализируются при загрузке класса, поэтому, даже если объект ученика не создан, вы все равно можете получить доступ и использовать статическую переменную имени.

Уровень объекта: Они будут инициализированы, когда вы создадите новый объект, скажем, с помощью new ();

C)
Твоя проблема : Ваш класс только что загружен в JVM, и вы вызвали его основной (статический) метод: Разрешено законом.

Теперь из этого вы хотите вызвать переменную объекта: Где находится объект ??

Вы должны создать объект. и только тогда вы сможете получить доступ к варибалам уровня объекта.

6
ответ дан 3 November 2019 в 12:50
поделиться

Вы, вероятно, захотите добавить «static» к объявлению con2.

В Java вещи (как переменные, так и методы) могут быть свойствами класса (что означает, что они совместно используются всеми объектами этого типа), или они могут быть свойствами объекта (разными для каждого объекта того же класса). Ключевое слово «static» используется для обозначения того, что что-то является свойством класса.

«Статический» материал существует постоянно. Остальные вещи существуют только после того, как вы создали объект, и даже тогда каждый отдельный объект имеет свою собственную копию. И обратная сторона этого является ключевой в данном случае: статический материал не может получить доступ к нестатическому материалу, потому что он не знает, какой объект искать. Если вы передадите ему ссылку на объект, он сможет делать такие вещи, как «штука .con2 ",

13
ответ дан 3 November 2019 в 12:50
поделиться

Простейшее изменение будет примерно таким:

public static void main (String[] args) throws Exception {
  testconnect obj = new testconnect();
  obj.con2 = DriverManager.getConnection(obj.getConnectionUrl2());
  obj.con2.close();
}
2
ответ дан 3 November 2019 в 12:50
поделиться
Другие вопросы по тегам:

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