Программа синхронизации Gradle на вашем хост-компьютере разорвала установленное соединение
Обновлено: 21.11.2024
Я пытаюсь прочитать канал, если селектор считает, что он доступен для чтения. Тем не менее, я получаю IOException: установленное соединение было прервано машиной из-за программного обеспечения на вашем хост-компьютере. Какие могут быть причины, по которым я сталкиваюсь с этим.
ПРИМЕЧАНИЕ. Я пытаюсь создать VPN-сервер. Открытие SocketChannel и передача данных с помощью WebSocket клиенту. Он работает на небольших HTML-страницах, но не работает в основном на страницах HTTP2. Вот где я получаю это "IOException"
ПРИМЕЧАНИЕ. Приведена только та часть, где я сталкиваюсь с ошибками. Есть несколько ненужных строк, которые я не удалил. Он написан на Котлине.
Смотрите также вопросы, близкие к этой теме
Мне очень нужно решение этой проблемы:
На планете Ксибо, где нет гравитации и широко распространены физически сомнительные гиперпространственные порталы, дети играют в классики на цилиндрической поверхности.
Гигантский цилиндр стоит вертикально, круглое основание находится на земле. Затем вокруг цилиндра наматывается прямоугольная сетка так, чтобы ее концы соприкасались друг с другом, и каждому квадрату на сетке присваивается положительное целое число баллов. Игроку необходимо войти в цилиндр из любой верхней или нижней позиции. Игрок будет прыгать вокруг цилиндра, суммируя очки на квадратах, которых коснулся по пути.
Правильный прыжок должен двигаться против часовой стрелки вокруг цилиндра (т. е. вправо в пределах сетки) и может быть только (а) прямо вправо (б) вправо и вверх на один (в) к вправо и вниз один. Если игрок покидает сетку и падает на землю, он снова входит в сетку через верхнюю часть цилиндра (через гиперпространственный портал).
Точно так же, если игрок покидает сетку через верхнюю часть цилиндра, он снова входит в сетку через нижнюю часть цилиндра (опять же, через гиперпространственный портал).
Игрок совершит только один обход вокруг цилиндра и должен выйти из цилиндра после завершения полного обхода через верхнюю или нижнюю часть, чтобы игрок попал в каждый столбец в цилиндре ровно один раз). Побеждает игрок с наибольшим общим счетом. Ваша задача — найти путь оптимального игрока.
Сетка будет представлена вам как двумерная матрица m x n, пронумерованная обычным для информатики способом (начиная с 0). Первое измерение будет представлять строки, а второе измерение будет представлять столбцы. Ваш путь будет состоять из списка целых чисел.
Первым будет 1 (сверху) или 0 (снизу), в зависимости от того, входит ли игрок в цилиндр сверху или снизу. Следующей будет колонка входа. После этой точки будет n-1 целое число движения: O означает двигаться прямо вправо, 1 означает двигаться вправо и вверх, -1 означает двигаться вправо и вниз.
Если вы пишете файл на Java: Student Solver.java должен иметь функцию с общедоступным статическим заголовком ArrayList для решения (сетка ArrayList)
Если вы пишете файл на C++: Student Solver.h должен иметь строку с заголовком static std::vectorsolve (std::vector > grid);
Пример. Рассмотрим ввод, заданный следующей сеткой:
Ответ должен быть: 1, 4, 0, 1, 1, 0, -1
Скажем, у меня есть два массива a= и b=. Как мне найти все возможные комбинации двух массивов, которые используют все элементы, но не нарушают порядок отдельных массивов, то есть, например, комбинация никогда не может начинаться ни с чего, кроме «a» или « 1", не заканчиваться на "a" или "1"
Я сохраняю данные о том, как долго пользователи держат кнопки, когда пишут. Теперь данные сохраняются в const holdTimes , но я хочу добавить любую кнопку в html, например SAVE, а затем отправить данные из js в мой JavaController.
Есть идеи, как создать JavaController и кнопку SAVE?
JavaController выглядит следующим образом:
Я начал изучать Kotlin несколько дней назад и не совсем понимаю, зачем в таком случае использовать readln(). toInt(), откуда берется число и к какой «строке» оно относится.
fun main(аргументы: Массив)
Было бы очень полезно, если бы кто-нибудь объяснил это. Спасибо!
Если пользователь сворачивает приложение Android во время длительной задачи, такой как вход в систему или вход в систему или любой другой вызов API, как управлять или обрабатывать состояние приложения в таких ситуациях?
Пользователи Интернета, мне нужна ваша помощь! Мне было поручено подключить модуль Android к проекту Unity. До сих пор у меня работало соединение, и теперь мне нужно контролировать размер представления одним нажатием кнопки в Unity. В этом отношении я создал собственный макет для UnityPlayerActivty и протестировал управление представлением в моей функции onCreate. Функция работает, когда я инициализирую объект, но при вызове из Unity я получаю сообщение об ошибке, упомянутое в заголовке
Функция инициализации (работает из моего onCreate)
при вызове из Unity (даже через другую внутреннюю функцию) не работает. помочь?
Библиотека, которую мне нужно использовать, записывает свой вывод в поток записи. Я хотел бы прочитать эти данные в строку (или в буфер), а не записывать их на диск.
Можно ли это сделать с помощью существующих библиотечных функций или мне нужно реализовать собственный буфер записи?
Другими словами, я хотел бы написать что-то вроде:
Существует ли что-то вроде InMemoryWriteStream?
Я пытаюсь получить данные со счетчика электроэнергии Elmeasure LG5120 через TTL-преобразователь MAX RS485. Я использую эту функцию Serial.println(node.getResponseBuffer(0x00)) to Serial.println(node.getResponseBuffer(0x05)); Выход был 0, может ли кто-нибудь указать мне правильное значение буфера, пожалуйста.
В Python 3.9 я написал TCP-сервер, который никогда не вызывает функцию receive(). И клиент, который отправляет на сервер фрагменты размером 1 КБ. Ранее я устанавливал размеры буферов отправки и получения в диапазоне КБ.
Я ожидал, что смогу отправить (буфер отправки + буфер приема) байты до того, как send() заблокируется. Однако:
- В Windows 10: send() последовательно блокирует только после (2 x буфера отправки + буфера приема) байтов.
- В Raspberry Debian GNU/Linux 11 (яблочко):
- установка захвата буфера (с помощью setsockopt) приводит к удвоению буфера (согласно данным getsockopt).
- send() блокирует примерно через (буфер отправки + 2 буфера приема) байт относительно размера буфера, установленного с помощью setsockopt.
Вопросы. Куда уходят "лишние" данные? Почему реализация ведет себя по-другому?
Все тесты проводились на одном и том же компьютере (win->win, raspi->raspi) с различными размерами буфера отправки/получения в диапазоне 5–50 КБ.
У меня есть папка плагинов, содержащая несколько JAR-файлов, и я хочу загрузить все их файлы *.class. Я вижу много ответов с вещами JarFile или ZipEntry. Однако я хотел бы сделать это, используя пакет java.nio, а не io.
- перечисление файлов в папке (например, перечисление всех моих банок) с использованием Files.list(Path)
- загрузка .class внутри JAR-файла, зная его точное местоположение в указанном JAR-файле.
Что я пока не могу сделать:
В конечном итоге я хочу:
- Просмотр каждого класса в нескольких JAR-файлах и их загрузка для поиска аннотации для своего рода системы плагинов.
Должен добавить, что мне не нужно работающее решение с использованием таких API, как Guava или Apache, но я просто хочу знать, как это делается.
Мой текущий код:
Я использую Java Selector как для сервера, так и для клиента. Для серверной части работает отлично. Он останавливает поток, когда я вызываю select(), и просыпается, когда я меняю процентные операции, и он готов к этой операции..
Но, к сожалению, это не работает так же для сокет-клиента. Он останавливает поток и не просыпается для чтения или записи, когда я меняю интересующие операции.
Создание соединения:
Обработка выбора внутри цикла while:
Итак. Изменение интереса из другого потока не работает для клиентов сокетов. Но он отлично работает для серверных сокетов..
Найденные решения:
- selector.select(300) -> использовать некоторое время ожидания для пробуждения селектора
- selector.selectNow() -> использовать неблокирующий метод и проверять количество событий
- selector.wakeUp() -> сохранить экземпляр и разбудить его вручную..
Вопрос в том, почему это не работает? Я сделал какую-то ошибку? Что-то пропустили?
В моем случае, когда я увеличиваю (активную) группу потребителей в Kafka, возникает некоторая задержка в производстве, потреблении, совершении.
Поэтому необходимо иметь глубокие знания о потоках ввода-вывода, сетевых потоках и других внутренних потоках, чтобы понять, что является узким местом.Для справки: в очереди запросов и ответов нет всплесков. Благодаря метрикам Grafana JMX сетевой поток большую часть времени простаивает.
Кто-нибудь может подробно объяснить работу потоков ввода-вывода и других потоков, сетевого буфера и т. д., что может быть узким местом.
Я пишу многопользовательскую текстовую игру (типичный MUD) и получил серверный код из другого проекта, используя библиотеку NIO.
Вот серверный код метода run для обработчика основного соединения (выполняется в выделенном потоке):
Затем я реализовал команду для выхода из игры следующим образом:
и работает правильно!
Затем я изменил этот метод, чтобы реализовать обратный отсчет перед отключением, чтобы игрок мог вводить команду во время обратного отсчета (чтобы игрок мог остановить отключение или выполнить другие действия).
Для этого я использовал классы Timer и TimerTask:
В этом случае после отключения игрока, если я попытаюсь повторно подключиться к серверу, клиент (telnet) будет зависать:
Я попытался использовать Thread вместо TimerTask с тем же результатом.
Я заметил, что если два игрока одновременно подключены и один из них отключается, клиент другого зависает, как описано выше.
Я предполагаю, что это, вероятно, проблема потока с SocketChannel, но я не могу понять причину, поскольку у каждого игрока есть свой собственный SocketChannel.
Мне нужен способ использовать разные селекторы для OP_READ и OP_ACCEPT. Я столкнулся с проблемой, когда скребки портов среди других подключающихся объектов задерживают рукопожатие и вызывают задержку для всех, кто зарегистрирован в OP_READ. Мое решение состояло в том, чтобы обрабатывать OP_READ и OP_ACCEPT в отдельных потоках, но у меня были проблемы. Сначала я регистрирую свой акцептор (селектор) в моем канале серверного сокета здесь.
после того, как я принимаю клиента, я регистрирую его канал сокета в селекторе, отличном от того, на котором он был принят:
Это сообщение устарело. Вместо этого ознакомьтесь с новым руководством по началу работы с Amplify Android, чтобы узнать, как создавать мобильные приложения Android с помощью AWS Amplify.
Это пошаговое руководство является первой частью серии из двух частей о том, как создать мобильное приложение AWS для Android с поддержкой облака с помощью набора инструментов AWS Amplify.
Предположим, вы хотите создать собственное приложение для Android, отображающее список домашних животных. Вы хотите настроить API для включения в список, создания и хранения данных о домашних животных, но вы не хотите управлять серверной инфраструктурой. Вы хотите сосредоточиться на создании приложения для Android. Вы также хотите включить аутентификацию пользователей, чтобы каждый пользователь мог добавить своего собственного питомца. В этом посте мы рассмотрим подробные пошаговые инструкции по созданию этого приложения для Android.
Мы рассмотрим, как сделать следующее:
- Добавьте GraphQL API, поддерживаемый AWS AppSync.
- Добавьте механизм аутентификации пользователей через Amazon Cognito.
- Включить запрос и отображение списка домашних животных в RecyclerView.
- Включить добавление новых данных о домашних животных и сохранение данных в серверной части.
Начало работы — настройка нового проекта Android
Предпосылки
Для начала на вашей рабочей станции должна быть установлена Java JDK. Скачайте и установите Android Studio, а затем загрузите Android 6.0 SDK (уровень API 23 или выше) в Android SDK Manager.
Кроме того, загрузите образ эмулятора. Для этого выберите AVD Manager в Android Studio. Выберите + Создать виртуальное устройство и следуйте инструкциям для завершения настройки.
Создать новый проект Android
Для начала нам нужно создать новый Android . Продолжайте и создайте новый проект Android, как показано ниже:
Выберите «Телефон» и «Планшет», выберите «API 23: Android 6.0 (Marshmallow)» и нажмите «Далее».
На экране "Добавить действие на мобильный" выберите "Основное действие". Нажмите «Далее», оставьте значения по умолчанию и нажмите «Готово», чтобы завершить настройку проекта.
Импортируйте SDK AWS AppSync и настройте приложение
Чтобы использовать AWS AppSync в нашем новом проекте Android, измените файл проекта build.gradle и добавьте следующую зависимость в скрипт сборки:
Затем в build.gradle приложения добавьте подключаемый модуль apply plugin: 'com.amazonaws.appsync' и зависимости для AWS AppSync и MqttServices. .
В результате ваш build.gradle должен выглядеть так:
Наконец, обновите файл AndroidManifest.xml, включив в него обновления для сетевых вызовов и автономных состояний. Также добавьте запись в разделе для MqttService, чтобы мы могли использовать подписки:
Создайте свой проект и убедитесь в отсутствии проблем.
Установка интерфейса командной строки AWS Amplify и инициализация нового проекта AWS Amplify
Теперь давайте установим AWS Amplify CLI и интегрируем его с нашим проектом Android, чтобы мы могли в полной мере использовать набор инструментов Amplify CLI.
Установите интерфейс командной строки AWS Amplify
Откройте терминал и выполните в командной строке следующее. Если он у вас уже установлен, запустите команду еще раз, чтобы получить последние обновления.
Инициализировать проект AWS Amplify
Далее инициализируем новый проект AWS Amplify для вашего приложения Android.
cd в корень проекта Android Studio в окне терминала и выполните следующее:
Введите следующее для каждого элемента:
- Выберите редактор по умолчанию: Visual Studio Code (или ваш любимый редактор)
- Выберите тип приложения, которое вы создаете: Android.
- Где находится ваш каталог Res: (app/src/main/res): нажмите Enter, чтобы принять значение по умолчанию.
- Вы хотите использовать профиль AWS? Д
- Пожалуйста, выберите профиль, который вы хотите использовать: по умолчанию
AWS CloudFormation — исходная инфраструктура для поддержки вашего приложения. После этого цепочка инструментов AWS Amplify CLI инициализирует новый проект, и вы увидите пару новых файлов и папок в каталоге проекта вашего приложения: amplify и .amplifyrc. Эти файлы содержат конфигурацию вашего проекта.
Добавление API GraphQL, добавление аутентификации и создание клиентского кода
Связка инструментов AWS Amplify предоставляет нам оптимизированный процесс создания API, добавления аутентификации и создания клиентского кода. Давайте начнем с выполнения следующей команды в корневом каталоге вашего приложения:
Введите следующее для каждого элемента:
- Выберите одну из перечисленных выше служб: GraphQL.
- Укажите название API: AmplifyAndroid
- Выберите тип авторизации для API: пул пользователей Amazon Cognito.
- Хотите ли вы использовать конфигурацию аутентификации и безопасности по умолчанию? Да, используйте конфигурацию по умолчанию.
- Есть ли у вас аннотированная схема GraphQL? Н
- Хотите создать управляемую схему? Д
- Что лучше всего описывает ваш проект: (например, "Todo" с идентификатором, названием, описанием)
- Вы хотите изменить схему сейчас? (Д/н) Д
При появлении запроса обновите схему до следующей:
Вернитесь к терминалу и нажмите Enter, чтобы продолжить.
Далее давайте отправим конфигурацию в ваш аккаунт AWS, выполнив:
Вам будет предложено добавить изменения:
- Вы уверены, что хотите продолжить? (Д/н) Д
Теперь вам предлагается сгенерировать код для вашего нового API:
- Хотите ли вы сгенерировать код для только что созданного GraphQL API (Да/нет) Да
- Введите шаблон имени файла запросов, изменений и подписок (app/src/main/graphql/**/*.graphql): нажмите Enter, чтобы принять значение по умолчанию.
- Хотите ли вы сгенерировать/обновить все возможные операции GraphQL — запросы, мутации и подписки (да/нет) да
AWS CloudFormation запускается снова, чтобы обновить только что созданный API и механизм аутентификации для вашего аккаунта AWS. Этот процесс может занять несколько минут.
После того как AWS CloudFormation завершит обновление ресурсов в облаке, вам будет предоставлена конечная точка GraphQL API, а сгенерированные операторы GraphQL станут доступны в вашем проекте.
Несмотря на то, что это прозрачно для вас, и мы можем сразу же начать использовать API, вы всегда можете изучить вновь созданные запросы GraphQL, мутации и подписки в Android Studio в app/src/main/graphql/com/amazonaws/amplify/ сгенерировано/graphql.
Создание приложения для Android
Наша серверная часть готова. Теперь давайте начнем использовать его в нашем приложении для Android!
Прежде чем начать, включите автоматический импорт, если вы еще этого не сделали. Мы используем много библиотек! Для этого откройте «Настройки» -> «Редактор» -> «Основные» -> «Автоматический импорт». Затем выберите Добавить однозначный импорт на лету.
Создайте и запустите свой проект, чтобы запустить процесс генерации клиентского кода. Этот процесс сборки gradle создает все нативные типы объектов, которые вы можете использовать сразу. Вы должны увидеть пустое приложение, как показано на следующем снимке экрана:
Если вам интересно, вы можете переключиться в представление «Проект» и перейти к app/build/generated/source/appsync/com/amazonaws/amplify/generated/graphql/, чтобы изучить все сгенерированные типы объектов, запросы, мутации и подписки на классы Java.
Добавить аутентификацию
Поскольку ранее мы настроили приложение для использования пула пользователей Amazon Cognito для аутентификации, нам необходимо интегрировать аутентификацию в наше приложение. Для простоты мы будем использовать встроенный пользовательский интерфейс для входа в библиотеку AWS Mobile для аутентификации Amazon Cognito.
Откройте файл build.gradle вашего приложения и добавьте следующие зависимости:
Щелкните правой кнопкой мыши каталог приложения и выберите «Создать» -> «Активность» -> «Пустая активность». Назовите свою активность AuthenticationActivity, установите флажок Launcher Activity и нажмите Finish.
В классе AuthenticationActivity.java измените класс следующим образом:
Теперь давайте удостоверимся, что AuthenticationActivity является нашей активностью запуска. Откройте AndroidManifest.xml и убедитесь, что блокировка указана для AuthenticationActivity следующим образом.Вы должны удалить и android:theme для MainActivity.
Наконец, давайте изменим activity_main.xml и MainActivity.java и удалим код, связанный с AppBarLayout, чтобы они выглядели следующим образом:
Создайте и запустите приложение в эмуляторе. Интерфейс входа должен выглядеть следующим образом:
Теперь добавим пользователя. В эмуляторе выберите «Создать новую учетную запись». Введите имя пользователя и выберите сложный пароль. Пароль должен состоять не менее чем из 8 символов и может включать прописные буквы, строчные буквы, специальные символы и цифры. Введите действительный адрес электронной почты, чтобы получить код подтверждения.
Выберите «Зарегистрироваться».
Если вы видите сообщение об ошибке, например "Невозможно разрешить хост "cognito-idp.us-east-1.amazonaws.com", дважды проверьте, подключен ли ваш эмулятор к Интернету. При необходимости перезапустите эмулятор.
Ваш код подтверждения вскоре придет на указанный вами почтовый ящик. Введите этот код на следующем экране и нажмите «Подтвердить», чтобы завершить процесс регистрации:
После того, как вы успешно вошли в систему, вы должны увидеть сообщение об успешном выполнении, а затем вернуться к тому же пустому экрану, который является нашей MainActivity.
Создайте клиент AWS AppSync
Теперь нам нужно создать AWSAppSyncClient для выполнения вызовов API. Добавьте новый класс ClientFactory.java в свой пакет:
Этот класс ClientFactory предоставляет клиент AppSync, который мы можем использовать для выполнения действий по доступу к данным.
Запрос данных
У нас пока нет данных в нашем списке, но давайте создадим возможность отображать их, когда у нас будут данные.
Добавить RecyclerView для отображения списка элементов
Теперь давайте начнем создавать наше приложение, чтобы включить отображение элементов.
Мы используем RecyclerView для отображения данных. Откройте src/res/layout/content_main.xml, переключитесь в текстовый режим и замените
со следующим:
Теперь давайте определим, как выглядит каждый элемент в нашем списке. Щелкните правой кнопкой мыши папку res/layout и добавьте новый файл ресурсов макета. Назовем его recyclerview_row.xml. Измените Root element на LinearLayout, оставьте остальные по умолчанию и нажмите OK.
Переключитесь на представление Text файла recyclerview_row.xml и измените макет следующим образом:
Поскольку мы используем RecyclerView, нам нужно предоставить для него адаптер. Добавьте новый класс Java MyAdapter.java, расширяющий RecyclerView.Adapter:
Обратите внимание на переменную уровня класса mData. Это список типа ListPetsQuery.Item, который является сгенерированным типом GraphQL, основанным на нашей схеме.
Мы также предоставили метод setItems, позволяющий выполнять внешний сброс нашего набора данных.
Создайте экран для заполнения RecyclerView
Откройте MainActivity.java, измените класс, чтобы реализовать метод запроса, и заполните RecyclerView:
appSyncClient отвечает за запросы к конечной точке AWS AppSync GraphQL. Мы решили использовать режим CACHE_AND_NETWORK, потому что он сначала извлекает данные из локального кеша, а за последними данными обращается к сети. После завершения выборки снова вызывается queryCallback, и наш набор данных обновляется последними данными. Существуют и другие режимы кэширования или сетевой/первый режимы, которые вы можете использовать, в зависимости от потребностей вашего приложения в извлечении данных.
Повторно создайте приложение, чтобы убедиться в отсутствии ошибок. Пустой экран по-прежнему отображается, но вы должны увидеть журнал в окне Logcat. Это указывает на успешное завершение запроса, как показано ниже:
09-28 10:32:16.789 11605-11699/com.example.demo.mypetapp I/MainActivity: Полученные элементы списка: []
Добавить питомца
Теперь добавим возможность добавления питомца.
Добавьте новую пустую активность, выбрав «Создать» -> «Активность» -> «Пустая активность». Назовите действие AddPetActivity и нажмите «Готово».
Откройте файл макета activity_add_pet.xml и добавьте следующий макет в существующий файл :
Это дает нам основные поля для ввода имен и описаний наших питомцев.
Откройте AddPetActivity.java и добавьте следующий код для чтения введенного текста. Создайте новую мутацию, которая добавит нового питомца.
Теперь давайте соединим AddPetActivity с нашей MainActivity.
Откройте файл макета activity_main.xml и замените плавающую кнопку после RecyclerView следующим:
Снова откройте MainActivity.java и измените существующий код в onCreate, чтобы AddPetActivity запускался при нажатии кнопки addPetbutton:
Теперь давайте создадим и запустим проект, а затем протестируем дополнительные функции.
Войдите в систему с ранее созданным именем пользователя и паролем, если вам будет предложено снова. Затем на пустом экране нажмите кнопку «+»:
После этого вы должны увидеть экран, предлагающий ввести имя и описание. Введите несколько тестовых значений, как показано ниже, чтобы добавить нашего первого питомца.
Нажмите «Сохранить», чтобы отправить мутацию для создания питомца. Создание должно быть успешным, и вы должны увидеть наш первый созданный элемент, отображаемый в списке. Это связано с тем, что ранее мы указали в onResume(), что делаем «повторную выборку», чтобы иметь самые последние данные.
Вот вы и создали приложение для Android, которое показывает вам список питомцев и позволяет добавлять питомцев!
Оставьте отзыв
Мы рады, что вы создали это приложение для Android. Прочтите вторую часть этой серии блогов. Вы сможете добавить автономную поддержку, подписки в реальном времени и хранилище объектов в свое приложение для Android. Как всегда, дайте нам знать, как у нас дела, и отправьте любые запросы в репозиторий AWS Amplify CLI. Подробнее об AWS Amplify можно узнать на веб-сайте AWS Amplify.
Джейн Шен (Jane Shen) работает архитектором приложений AWS Professional Services в Торонто, Канада.
Приложения на Heroku могут использовать различные службы реляционных баз данных, включая базу данных Postgres, предлагаемую Heroku.
Базы данных предоставляются с помощью дополнительной системы. Некоторые приложения будут иметь небольшую бесплатную базу данных postgres по умолчанию. Вы можете проверить это, запустив
и найдите «Heroku Postgresql Dev» в разделе «Дополнения». Автоматическая подготовка базы данных зависит от пакета сборки. Вы можете подготовить базу данных dev вручную с помощью
База данных dev предназначена для тестирования. Для рабочего приложения вы должны использовать одну из баз данных Heroku Postgres или надстройки SQL.
После предоставления реляционной базы данных вашему приложению. Приложение считывает информацию о подключении к базе данных из переменной конфигурации DATABASE_URL. Он имеет следующий формат:
Вы можете просмотреть DATABASE_URL, предоставленный приложению, выполнив:
Не рекомендуется копировать это значение в статический файл, поскольку среда может изменить значение. Вместо этого приложение должно прочитать переменную среды DATABASE_URL (или переменную JDBC_DATABASE_URL, описанную ниже) и настроить соединения с базой данных на основе этой информации.
Использование JDBC_DATABASE_URL
Официальные сборки Heroku для Java, Scala, Clojure и Gradle будут пытаться создать переменную среды JDBC_DATABASE_URL при запуске динамического стенда. Эта переменная является динамической и не будет отображаться в вашем списке переменных конфигурации при запуске heroku config. Вы можете просмотреть его, выполнив следующую команду:
Переменная будет включать ?user= &password=
параметры, но по возможности также будут установлены переменные среды JDBC_DATABASE_USERNAME и JDBC_DATABASE_PASSWORD.
Официальным источником URL-адреса базы данных по-прежнему является переменная среды DATABASE_URL, но в большинстве случаев можно использовать JDBC_DATABASE_URL.
Пакет сборки Java также установит JDBC_DATABASE_URL для надстроек ClearDB MySQL, JawsDB MySQL и JawsDB Maria.
Для баз данных, использующих формат HEROKU_POSTGRESQL_, сборочный пакет Java создаст переменные конфигурации HEROKU_POSTGRESQL_ _JDBC_URL, HEROKU_POSTGRESQL_ _JDBC_USERNAME и HEROKU_POSTGRESQL_ _JDBC_PASSWORD.
Использование SPRING_DATASOURCE_URL в приложении Spring Boot
Официальные пакеты сборки Heroku для Java и Gradle будут пытаться создать переменные среды SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME и SPRING_DATASOURCE_PASSWORD при запуске динамического стенда.Значения переменных будут идентичны значениям соответствующих переменных JDBC.
Если ваше приложение имеет правильный драйвер JDBC, определенный как зависимость, эти переменные среды должны позволять вашему приложению Spring Boot подключаться к базе данных без какой-либо другой настройки.
Если вам нужно переопределить предопределенные переменные среды SPRING_DATASOURCE_*, вы можете установить их самостоятельно с помощью команды heroku config:set или установить их на панели инструментов. Кроме того, вы можете добавить свойство -Dspring.datasource.url в свой Procfile , которое будет иметь приоритет над переменными среды уровня ОС.
Использование JDBC_DATABASE_URL в приложении Spring Boot
Spring Boot позволяет внедрить вашу конфигурацию, чтобы вы могли работать с одним и тем же кодом приложения в разных средах. Вы можете использовать файлы свойств, файлы YAML, переменные среды и аргументы командной строки для внешней конфигурации.
Вы можете указать URL своей базы данных в файле application.yml следующим образом:
Для получения дополнительной информации см. официальную документацию Spring по внешней конфигурации.
Использование DATABASE_URL в приложении Play Framework
Play Framework поддерживает переменную среды DATABASE_URL по умолчанию. Встроенную структуру ORM можно настроить для использования этого значения, добавив его в ваш conf/application.conf :
При использовании Slick с Play Framework конфигурация выглядит следующим образом:
Для получения дополнительной информации см. документацию Play для модуля Play Slick.
Использование DATABASE_URL в простом JDBC
Чтобы создать соединение JDBC в коде, вы можете использовать следующий метод:
При непосредственном использовании DATABASE_URL это будет выглядеть так:
Примечание:
DATABASE_URL для надстройки Heroku Postgres соответствует приведенному ниже соглашению
Однако драйвер Postgres JDBC использует следующее соглашение:
Обратите внимание на дополнительный ql в конце схемы URL. Из-за этой разницы для Postgres вам может потребоваться жестко запрограммировать схему для postgresql в вашем классе Java или в конфигурации Spring XML.
Использование DATABASE_URL в Spring с конфигурацией XML
Этот фрагмент конфигурации Spring XML установит BasicDataSource из DATABASE_URL, а затем его можно будет использовать с Hibernate, JPA и т. д.:
Использование DATABASE_URL в Spring с конфигурацией Java
В качестве альтернативы вы можете использовать Java для настройки BasicDataSource в Spring:
При непосредственном использовании DATABASE_URL это будет выглядеть так:
Снова обратите внимание на разницу в подпротоколе. DATABASE_URL использует postgres, а JDBC требует значение postgresql .
Использование DATABASE_URL с Hibernate
Если вы настраиваете Hibernate вручную с помощью файла hibernate.cfg.xml вне какой-либо другой платформы, вы можете установить URL-адрес JDBC в коде Java при создании реестра службы. Например:
Это переопределит любую настройку URL в файле hibernate.cfg.xml .
Использование SSL с PostgreSQL
Раньше мы предлагали добавить параметр sslmode=disable к URL-адресам JDBC. Теперь мы требуем использования SSL для всех новых баз данных Heroku Postgres. Мы будем принудительно использовать SSL во всех базах данных Heroku Postgres с марта 2018 года. Не отключайте SSL для своей базы данных, иначе ваши приложения могут выйти из строя.
По умолчанию Heroku попытается включить SSL для драйвера JDBC PostgreSQL, установив свойство sslmode=require глобально. Использование SSL требуется для всех подключений к базе данных на Heroku Postgres. Режим sslmode по умолчанию задается в небольшом файле свойств, который автоматически добавляется в путь к классам. Вы предотвращаете внедрение этого файла, запустив heroku config:set SKIP_PGCONFIG_INSTALL=true .
Драйверы для баз данных других поставщиков не затрагиваются.
Удаленное подключение к базе данных
Если вы используете базу данных Heroku Postgres, вы можете подключиться к ней удаленно для обслуживания и отладки. Однако для этого необходимо использовать SSL-соединение. Ваш URL-адрес подключения JDBC должен включать параметр URL:
Если вы не добавите sslmode=require, вы получите ошибку подключения.
Дополнительную информацию о поддержке SSL с помощью драйвера Postgres JDBC см. в официальной документации PostgreSQL. Для других баз данных SQL обратитесь к документации JDBC вашего поставщика, чтобы узнать, как настроить поддержку SSL.
Важно добавить этот параметр в код, а не напрямую редактировать переменную конфигурации. Различные автоматические события, такие как отработка отказа, могут изменить переменную конфигурации, и внесенные в нее изменения будут потеряны.
При подключении к базе данных Private или Shield через mTLS в URL-адресе подключения JDBC требуются дополнительные параметры. Дополнительную информацию см. в нашей документации по подключению через mTLS.
Выполнение миграции базы данных
Большинству баз данных в какой-то момент потребуется изменить схему.Инструменты миграции, такие как Liquibase и Flyway, контролируют историю версий этих изменений. Вы можете узнать, как запустить их на Heroku, в статье Запуск миграции баз данных для приложений Java
Использование пула соединений Heroku Postgres
При использовании JDBC с пулом соединений Heroku Postgres для JDBC_DATABASE_URL будет установлено значение, определенное в переменной конфигурации DATABASE_CONNECTION_POOL_URL.
Пример проекта
Чтобы попробовать, сначала клонируйте репозиторий git:
В каталоге devcenter-java-database запустите сборку Maven для проекта:
Если у вас есть локальная база данных Postgres и вы хотите протестировать ее локально, сначала задайте переменную среды DATABASE_URL (используя правильные значения):
Чтобы запустить примеры приложений локально, выполните сгенерированные сценарии запуска:
Для каждой команды вы должны увидеть сообщение, подобное следующему, указывающее, что все работает:
Читайте также: