Задать вопрос
Ответы пользователя по тегу Spring
  • Как получить данные со стороннего ресурса?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Так как вы работаете со Spring, то посмотрите в сторону RestTemplate
    https://www.baeldung.com/rest-template
    Ответ написан
    Комментировать
  • Почему не создается бин jpaRepository?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Удалось ли вам решить проблему?
    Если нет, то поделюсь некоторыми мыслями, а вы уже продебажьте ваш код.
    Первый раз деплою. через идею все нормально отрабатывает, но при попытке задеплоить на vps выдает ошибку

    Если у вас локально отрабатывает корректно, а на VPS нет, то проверьте конфигурацию сервера. В вашем проекте на гитхаб application.yaml пустой и соответственно, непонятно что именно у вас прописано в конфигах для production. Если у вас есть профили, то проверьте установлен ли hibernate.ddl-auto: validate и если установлен, то импортировали ли вы ddl & dml на сервер. Или у вас он на production должен создать ddl сам?
    Как минимум, это первый момент на что стоит обратить внимание.

    Далее стоит уточнить деплоите ли вы приложение на внешний томкат или используете embedded?
    Далее попробуйте добавить такой класс в ваш проект:

    public class ServletInitializer extends SpringBootServletInitializer {
    
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(App.class);
      }
    }


    Далее обратите внимание на то, как именно вы собираете build и что в него добавляете. Например, war exploded или war или jar. Есть ли все необходимые классы в нем и т.д.

    Если сборка происходит через Gradle, то используйте bootWar. В общем, нужно проводить дебаг и смотреть что не так
    Ответ написан
  • Парсинг (скрапинг) получение информации с сайтов, авторизация, инструменты, примеры?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Начнем с простого, когда контент сайта загружается без фреймворков. Соответственно, нет никаких аяксов, не нужно никуда скроллить, чтобы получить следующую страницу или кликать на кнопки и т.д. для получения материалов. Т.е. вам достаточно отправить GET запрос на некий сайт и получить данные.
    В этом случае для парсинга будет достаточно библиотеки jsoup. Либо для своей кастомной реализации используйте DOM & SAX Parser.

    Теперь, чуть усложним задачу сайт точно также формируется без фреймворков, но для получения доступа к информации нужна авторизация. Если тут используется какая-то простая авторизация, то достаточно будет единожды получить кукисы и при каждом запросе указывать на сервер. Также не забывайте про referrer & User-agent.

    Теперь, еще усложним задачу - контент формируется динамически (посредством js-фреймворков или аякс запроса и т.д.). В этом случае jsoup не поможет, так как для загрузки контента вам нужно прокликать на кнопку (Загрузить еще) или проскроллить вниз, чтобы тригернуть загрузку контента и т.д. Т.е. вам нужна некая интерактивность. Для этого стоит посмотреть в сторону Selenium + (любой браузер). В качестве браузера можно использовать - firefox, chromium и др. Для быстродействия желательно использовать headless браузеры.

    Усложняем задачу дальше. Понадобилось авторизоваться и решить некую капчу. В часности рекапчу. Тут скажу заранее, что я сам когда-то давно искал возможные пути обхода и самое простое решение - использовать платный сервис.
    Ссылка на сайт - https://anti-captcha.com/
    После ввода имени пользователя и пароля селениум триггерит клик на капче, а дальше данные пересылаем на сервер и получаем решение капчи.

    Усложним задачу еще больше - различные honeypot. Тут как говорится кто на что горазд. Все зависит от конкретного сайта и конкретной реализации (софта) honeypot. Некоторые могут заблокировать по ip, если запрос был произведен на несуществующий урл. Например, на сайте всего 100 страниц, а вы запросили 101 страницу и попались в ловушку. Или например, вы заполнили невидимое input поле, которое в норме пользователь не видит и соответственно, не заполняет.

    Идем дальше - если вам нужна некая интерактивность (т.е. пользователь сайта должен иметь возможность самостоятельно парсить сайт), то вам нужна клиентская часть написанная на javascript. Подобные онлайн-сервисы имеются. Наберите в гугл web scraping online и увидите различные сервисы. Как правило, они предлагают установить некое расширение, при клике на котором он получает доступ к элементам DOM, а далее уже можно при помощи селекторов (id, xpath, class ) определить что нужно спарсить. Определить тип навигации / пагинации (например, пагинация при помощи нумерации страниц или пагинация при помощи кнопки Далее и др.). Тут могут свои подводные камни. Например, некоторые сайты при достижении максимальной страницы могут выдавать ошибку (404), некоторые не выдают ошибку и лишь показывают контент заново. Иногда нужно проверять страницу на наличие пустоты на странице (на отсутствие элементов по селектору). Иногда нужно проверять страницу на наличие ошибки 404 и т.д. В общем, это уже работа фронтэндера.

    Некоторые динамически формируемые страницы могут подгружать контент при помощи json или xml. Соответственно, для парсинга некоторых сайтов можно обойтись без использования selenium. А лишь запросить материалы по их внутреннему API, а затем при помощи gson или jackson спарсить их.

    Одним из универсальных инструментов парсинга, с которым мне приходилось сталкиваться была программа Visual Web Ripper. Стоит примерно 250-300 долларов. Программа подгружает контент сайта внутри себя через IE (может уже и обновили этот момент). А далее уже можно задавать условия парсинга и экспортировать данные.
    Ответ написан
    Комментировать
  • Что делать: ошибка в компиляции, связанная с Spring Data репозиторием (Не создаётся бин)?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    IllegalArgumentException: Validation failed for query for method findByBody(String body)

    Вот, краткий лог ошибки. Ошибка валидации метода.
    Могу предположить тут 2 проблемы:

    Вот, ваш код:
    public interface ExpressionRepository extends CrudRepository<ExpressionEntity, Long> {
    
        @Query("FROM ExpressionEntity WHERE ExpressionEntity.body = body")
        public Optional<ExpressionEntity> findByBody(String body);
    
    }


    Скорее всего должно быть так:
    SELECT e FROM ExpressionEntity e WHERE e.body = ?1
    Ответ написан
  • Как реализовать роли пользователей для Spring security?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    добавлять роли для пользователей (non-user, user, admin) со своими паролями и логинами.

    У ролей не бывает логинов и паролей. Они есть у пользователей.
    Роль лишь определяет то, кем данный пользователь является. ADMIN, USER, etc.
    Также есть Privilege (привилегия). Т.е. что данному пользователю разрешено согласно выданному ему ролю. Например, право на комментирование, право на публикацию и т.д.
    Вот, тут наглядный туториал по ролям и привилегиям
    https://www.baeldung.com/role-and-privilege-for-sp...
    Вот, неплохой курс с торрента:
    https://rutracker.org/forum/viewtopic.php?t=5864776
    Рекомендую приобрести данный курс на оф. сайте baeldung.com
    Ответ написан
    Комментировать
  • Правильно ли я выбрал конфигурацию для проекта с использованием spring?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Создаю restfull web-framework на Kotlin

    Выбирайте, что вам угодно и чем вы лучше всего владеете.

    Maven в качестве сборщика, потому что Gradle не всегда стабильно работает

    Не факт насчет грейдла. Но maven подойдет.

    Packaging: JAR-архив, так как его проще запускать

    Тут зависит от ваших целей. Если вам нужен self-contained application, то jar подойдет. При деплое создать initd сервис и приложение взлетит. В случае с WAR надо бы отдельно томкат или еще что поднять...

    JVM: 8, чтобы охватить большее количество устройств

    JDK 11 насколько мне известно в данном случае лучше. Возможно, что ошибаюсь

    Spring Web, Spring Data JPA, PostgreSQL Driver, Spring Actuator

    Ну тут выбирать нужно то, что вам необходимо.
    Ответ написан
    Комментировать
  • Как загружать файлы, чтобы иметь к ним доступ потом?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Вы загружаете файлы в директорию resources, но чтобы они были доступны вам нужно перекомпилировать проект заново. Обычно, если в приложении подразумевается какая-то логика загрузки файла, то файлы загружаются в другую директорию вне проекта. Например, /home/example.com/uploads А путь к файлу и т.д. храниться в БД. При надобности можно обращаться к БД и доставать путь к файлу с названием и отдавать на клиент. Если об этом речь....
    Ответ написан
    Комментировать
  • Как подменить схему базы данных в Entity Hibernate?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Если я правильно понял, то у вас есть база, в которой есть 2 схемы. И в зависимости от профиля вы хотите переключать схемы?

    Я вижу тут пару вариантов:
    1) на уровне gradle || maven определить схемы.
    https://stackoverflow.com/questions/47240702/jpa-e...
    https://stackoverflow.com/questions/1149352/using-...
    <profiles>
        <profile>
          <id>production</id>
          <properties>
            <schema.name>production_schema_name</schema.name>
          </properties>
        </profile>
        <profile>
          <id>test</id>
          <properties>
            <schema.name>test_schema_name</schema.name>
          </properties>
        </profile>
    </profiles>

    2) использовать различные БД для разных профилей. Т.е. создать 2 БД по одной для каждого профиля.
    3) Создать 2 пакета (dev, prod) с сущностями, где для каждой из сущностей указывать:
    Для сущностей development
    @Table(name = "VALUES", schema = "DEV").
    Для сущностей production
    @Table(name = "VALUES", schema = "PROD").
    Ну и использовать аннотацию @Profile
    Ответ написан
    Комментировать
  • Как сохранять файлы на google диск с помощью Spring?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Не совсем понимаю, вы реализовали методы для работы с API Google Drive? Если нет, то для начала прочитайте документацию по работе с АПИ Гугл Диска.
    https://developers.google.com/drive/api/v3/about-sdk

    Вот, как надо реализовать загрузку файла на диск
    https://developers.google.com/drive/api/v3/manage-...

    Ну а дальше уже читайте...
    Ответ написан
    Комментировать
  • Spring Security не понимаю, как работает?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    А что если запрашиваемого пользователя не существует? Тогда что делать? как Spring-у сообщить что такого пользователя нет?

    Зачем Spring-y что-то сообщать? Если юзера нет, то будет выброшено исключение throws UsernameNotFoundException
    Или вас интересует что-то другое?
    Ответ написан
    4 комментария
  • Как поменять тип столбца в postgresql через spring boot?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Вы можете задавать length. Например,
    @Column (length = 2000)
    private String message;

    https://www.baeldung.com/jpa-size-length-column-di...
    или
    Использовать аннотацию @Lob
    https://www.baeldung.com/hibernate-lob
    Ответ написан
    Комментировать
  • Как напимер работать с api вконтакте или другими сервисами использующими Basik Autentification?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Для работы с API других сайтов вы можете использовать RestTemplate.
    В статье описано, как с ним работать. Как слать POST GET и др. запросы. Как получать ответы и как этот ответ разобрать в pojo
    https://www.baeldung.com/rest-template

    Вот, например, реализованный метод для получения статуса сервиса hotelbeds
    public HttpStatus getStatus() {
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity httpEntity = new HttpEntity(hotelbedsAuth.hotelsAuth());
            ResponseEntity<String> response = restTemplate.exchange(
                    hotelbedsProperties.getHotelBaseUrl()+"/status", HttpMethod.GET, httpEntity, String.class);
            return response.getStatusCode();
    }

    В общем, прочитайте про RestTemplate.

    Once the bearer token expires, you will have to use Basic Authorization again to obtain a new bearer token.

    Тут вы можете использовать CRON или аннотацию @Scheduled, чтобы по крону в заданный интервал времени запускать метод по обновлению токена

    https://www.baeldung.com/spring-scheduled-tasks
    Ответ написан
    1 комментарий
  • Как в Spring из FilterChain отправить ModelAndView?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Думаю, что вот тут ответ на ваш вопрос -
    https://stackoverflow.com/questions/3616763/settin...
    В частности:
    i think this is not possible, because this is a servlet filter, which would be applied after the spring request mapper servlet was applied. so basically, the request mapper servlet thinks it is finished, and passes the request back to the servlet container.
    view names only work INSIDE of spring - outside of spring, in the servlet container, you will have to talk about urls, not view names.
    Ответ написан
    Комментировать
  • Как в Spring Security переименовать таблицу mysql "persistent_logins"?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Нуу... как по мне тут довольно ясно говорится о том, что нужно сделать.
    Создайте класс и расширьте класс JdbcDaoSupport. Затем имплементируйте класс PersistentTokenRepository. Используйте этот класс, как spring bean.
    Далее в конфигах пропишите этот класс в атрибуте - token-repository-ref
    Ответ написан
    Комментировать
  • Spring application.properties как сделать?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Запросто...
    1) Создайте класс например,
    @Configuration
    @ConfigurationProperties(prefix = "custom")
    public class AppProperties {
    
    // названия полей должны соответствовать названиям из properties. 
    private String baseUrl;
    private String uploadPath;
    
    // тут геттеры 
    }


    А вот, пример application.properties
    custom.base_url=http://localhost:8080
    custom.upload_path=/home/example.com/uploads


    Spring сам уже связывает base_url к baseUrl и т.д.
    Единственное, @ConfigurationProperties(prefix = "custom")
    тут в prefix укажите тот префикс, который вам нужен. Т.е. тут custom.base_url custom является префиксом.

    Подробности тут - https://www.baeldung.com/configuration-properties-...
    Ответ написан
    3 комментария
  • Spring Security - Не работает POST метод?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Попробуйте после .loginProcessingUrl("/login") добавить:
    .usernameParameter("email")
    .passwordParameter("password")

    https://www.websparrow.org/spring/spring-boot-secu...
    По дефолту прибегает Spring Security ожидает username & password, а у вас email & password
    Ответ написан
  • Spring как передать значение между методами контроллера?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    Используйте SessionAttribute для этого
    https://stackoverflow.com/questions/37433863/how-t...
    Ответ написан
    Комментировать
  • Можете посоветовать туториал по Spring Framework/Spring MVC?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Здравствуйте!
    В первую очередь книга Spring in Action
    На youtube вроде неплохой туториал по основам Спринга - https://www.youtube.com/channel/UC2KfmYEM4KCuA1Zur...
    Я еще проходил вот, этот курс - https://www.udemy.com/course/spring-boot-intro/
    Для начала разработки этого хватит. А дальше уже развивайтесь.
    + spring.io baeldung.com
    Ответ написан
    1 комментарий
  • Как передать Юзера?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Форму регистрации нужно отправлять не GET запросом, а POST запросом.
    С учетом того, что вы используете thymeleaf вы можете саму форму привязать к объекту и получить сразу готовый объект. Обратите внимание на тег th:object
    https://o7planning.org/ru/12385/using-thymeleaf-th...

    Вот, хороший пример:
    https://stackoverflow.com/questions/32045271/how-t...
    <form th:action="@{/the-action-url}" method="post"
        th:object="${myEntity}">
    
        <div class="modal-body">
            <div class="form-group">
                <label for="name">Name</label> <input type="text"
                    class="form-control" id="name" th:field="*{name}"> </input>
            </div>
    
            <div class="form-group">
                <label for="description">Description</label> <input type="text"
                    class="form-control" id="description"
                    th:field="*{description}"> </input>
            </div>
        </div>
    </form>


    Ну или же в контроллере получаете просто ссылку на объект User user.
    Далее через сеттеры устанавливаете значения полученные из @ModelAttribute и сохраняете.
    Приведу пример:
    @PostMapping("/register")
    public String register(
    @ModelAttribute("username") String username,
    @ModelAttribute("password") String password,
    User user
    ) {
    user.setUsername(username);
    user.setPassword(password);
    userRepository.save(user);
    return "index";
    }
    Ответ написан
  • Почему вместо аннотации @Autowired рекомендуют использовать конструктор?

    azerphoenix
    @azerphoenix Куратор тега Java
    Java Software Engineer
    Я и сам изучаю пока что Spring.
    Прежде всего рекомендую прочитать книгу Spring in action. Там описаны все возможности DI и их преимущества.
    1 - DI property
    @Autowired
    private SomeClass someClass

    2 - DI setter
    3 - DI constructor
    @Autowired
    private final SomeClass someClass;
    SomeService (SomeClass someClass) {
    this.someClass = someClass;
    }


    Насчет использования аннотации @Autowired
    Использование этой аннотации необязательно в принципе. Но если например для класса имеется несколько конструкторов, то нужно для одного из них добавить аннотацию.

    Я например, в своих pet проектах использую так:
    @RequiredArgsConstructor
    public class PageController {
    private final SomeClass1 someClass1;
    private final SomeClass2 someClass2;
    private final SomeClass3 someClass3;
    }

    Т.е. подключаю lombok и использую DI конструктором...
    Ответ написан