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

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    В конфигурации нужно включить форм-авторизацию:
    @Configuration
        public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http
                    //твои
                    //настройки
                    .formLogin();
            }
        }
    Ответ написан
    Комментировать
  • Как сделать валидацию данных?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Я на практике использую следующий подход: для каждой хранимой сущности, которую может создать/изменить пользователь, я создаю класс, описывающий форму (иногда бывает, что для редактирования и создания используются даже разные классы в виду разного набора полей).
    Это делается по двум причинам: во-первых - не все поля в хранимой сущности пользователи могут создавать/изменять (например, даты создания/редактирования и идентификаторы), во-вторых - вынесение аннотаций валидации из класса сущности.

    Теперь ближе к делу: для валидации существуют аннотации из пакета javax.validation.constraints, а также дополнительные, предоставляемые реализациями Bean Validation API (например @Email из Hibernate Validator).

    Допустим, у нас есть класс, представляющий собой форму регистрации:
    SignUpForm.java
    public class SignUpForm {
        @Email
        private String email;
    
        @Size(min = 8)
        @Pattern(regexp = "какая-нибудь регулярка для проверки надёжности пароля")
        private String password;
    }


    В контроллере мы будем принимать форму таким образом:
    SignUpController.java
    public class SignUpController {
        public ResponseEntity signUp(@RequestBody @Valid SignUpForm form, BindingResult bindingResult) {
        }
    }



    В form будут содержаться данные, отправленные пользователем, а в bindingResult - результат валидации, который можно легко проверить, вызвав bindingResult.hasErrors(). Отмечу только то, что аргумент класса BindingResult должен быть сразу после аргумента, помеченного аннотациями @RequestBody и valid, в других случаях валидация работать не будет.

    Но дальше - больше. Допустим, нам нужно добавить поле для подтверждения пароля и проверять его соответствие паролю. В таком случае нам надо добавить свою аннотацию (в данном случае на класс) и валидатор.
    Новый класс формы:
    SignUpForm.java
    @PasswordMatch
    public class SignUpForm {
        @Email
        private String email;
    
        @Size(min = 8)
        @Pattern(regexp = "какая-нибудь регулярка для проверки надёжности пароля")
        private String password;
    
        private String passwordConfirmation;
    }


    Аннотация:
    PasswordMatch.java
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = PasswordMatchValidator.class)
    @Documented
    public @interface PasswordMatch {
    
        String message() default "{constraints.passwordmatch}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
        @Target({TYPE, ANNOTATION_TYPE})
        @Retention(RUNTIME)
        @Documented
        @interface List {
    
            PasswordMatch[] value();
        }
    }


    Ну и валидатор:
    PasswordMatchValidator.java
    public class PasswordMatchValidator implements ConstraintValidator<PasswordMatch, SignUpForm> {
    
        @Override
        public void initialize(PasswordMatch constraintAnnotation) {
        }
    
        @Override
        public boolean isValid(SignUpForm value, ConstraintValidatorContext context) {
                return Objects.equals(value.getPassword(), value.getPasswordConfirmation());
        }
    }


    И ещё один способ валидации - при помощи спринговых валидаторов. Допустим, нам нужно проверить существование указанного email в нашей БД, что вполне вписывается в процесс валидации. В таком случае пишем валидатор:
    SignUpFormValidator.java
    public class SignUpFormValidator implements Validator {
        public boolean supports(Class<?> type) {
            return SignUpForm.class.isAssignableFrom(type);
        }
        public void validate(Object target, Errors errors) {
            SignUpForm form = (SignUpForm) target;
            // проверяем, что нужно и добавляем ошибки в errors, если они есть
        }
    }


    Регистрируем его в контроллере:
    SignUpController.java
    public class SignupController {
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            binder.addValidators(new SignUpFormValidator());
        }
    }


    После этого Spring будет производить дополнительную валидацию при помощи этого валидатора.

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

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Если в рамках WebMVC, то из контроллера во вьюхи можно и DTO передавать. В обратную сторону (т.е. от клиента при отправке формы) - лучше иметь отдельные классы, представляющие собой набор полей форм (с точки зрения валидации удобнее).
    Если в рамках REST, то есть такой зверь как HATEOAS.
    Ответ написан
    Комментировать
  • Где хранить данные для авторизации?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Сами данные авторизации лучше хранить в файле конфигурации. Оттуда они должны доставаться контекстом приложения и подставляться в свойства класса-клиента API. Как-то так.
    Ответ написан
    Комментировать
  • В каких случаях может потребоваться JNDI?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    JNDI можно использовать для доступа к общим ресурсам, вроде соединений с БД, очередей сообщений, конфигурационных переменных. К примеру, можно в настройках сервера приложений создать соединение с БД, которое будет использоваться несколькими приложениями.
    Однако, сейчас JNDI становится менее популярным инструментом, так как современные приложения разворачиваются в большинстве случае не в серверах приложений. Для распределённой конфигурации сейчас есть такие инструменты, как Spring Cloud Config, Apache Zookeeper, Consul и прочие.
    Ответ написан
    Комментировать
  • Spring: Как сделать аутентификацию на основе bearer токена?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    1. Класс, реализующий Authentication.
      TokenAuthentication.java
      public class TokenAuthentication extends AbstractAuthenticationToken {
          private final Object principal;
          private final Object credentials;
          public TokenAuthentication(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
              super(authorities);
              this.principal = principal;
              this.credentials = credentials;
              this.setAuthenticated(true);
          }
          public TokenAuthentication(Object principal, Object credentials) {
              this(principal, credentials, null);
          }
          @Override
          public Object getPrincipal() {
              return principal;
          }
          @Override
          public Object getCredentials() {
              return credentials;
          }
      }

    2. Фильтр, с которого начнётся процесс аутентификации пользователя. Фильтр должен создать объект типа Authentication и попробовать аутентифицировать его при помощи AuthenticationManager.
      TokenHeaderAuthenticationFilter.java
      public class TokenHeaderAuthenticationFilter extends OncePerRequestFilter {
      
          private final AuthenticationManager authenticationManager;
      
          public TokenHeaderAuthenticationFilter(AuthenticationManager authenticationManager) {
              this.authenticationManager = authenticationManager;
          }
      
          @Override
          protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
              if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
                  filterChain.doFilter(servletRequest, servletResponse);
                  return;
              }
              String headerValue = servletRequest.getHeader("X-Authorization");
              if (StringUtils.isEmpty(headerValue)) {
                  filterChain.doFilter(servletRequest, servletResponse);
                  return;
              }
              String token = headerValue.split("\\s")[1];// ну или headerValue.replace("Bearer ")
              TokenAuthentication authenticationToken = new TokenAuthentication(null, token);
              authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(servletRequest));
      
              Authentication authenticationResult = authenticationManager.authenticate(authenticationToken);
              SecurityContextHolder.getContext().setAuthentication(authenticationResult);
              filterChain.doFilter(servletRequest, servletResponse);
          }
      }

    3. Класс, реализующий AuthenticationProvider. Этот класс и будет производить аутентификацию полученных данных.
      TokenAuthenticationProvider.java
      public class TokenAuthenticationProvider implements AuthenticationProvider {
          @Override
          public boolean supports(Class<?> authentication) {
              return TokenAuthentication.class.isAssignableFrom(authentication);
          }
          @Override
          public Authentication authenticate(Authentication authentication) throws AuthenticationException {
              // здесь должна быть реализована логика аутентификации полученных данных
          }
      }

    4. Последний штрих - конфигурация.
      SecurityConfig.java
      @Configuration
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      
          @Bean
          public AuthenticationProvider tokenAuthenticationProvider() {
              return new TokenAuthenticationProvider();
          }
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.addFilterAfter(new TokenHeaderAuthenticationFilter(authenticationManagerBean()), BasicAuthenticationFilter.class)
                      .authenticationProvider(tokenAuthenticationProvider())
                      .authorizeRequests()
                      .anyRequest().authenticated();
          }
      }

    Ответ написан
    Комментировать
  • Java EE умер, есть ли смысл делать на нем проекты?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Стоит ли сейчас разрабатывать web-проекты с использованием Java EE

    Вполне себе стоит, если душа не лежит к Spring или не позволяет корпоративная этика

    насколько я понял его пустили в свободное плавание на github

    Такое себе "свободное" плавание. ИМХО, выход из-под крыла Oracle только в плюс пойдёт.

    Насколько зависим Spring от Java EE ?

    Spring Web зависит от Servlet API, может использовать в качестве отображений JSP, а также интегрирован с JSF. Spring Data JPA, как видно из названия, основан на JPA. Есть возможность использования JMS. И т.д. в целом, т.е. Spring очень тесно связан с Java EE
    Ответ написан
    2 комментария
  • Unity3D server. Node.js или Java?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Зная возможности и ноды и жабы, выбрал бы Java с использованием Netty, во всяком случае на нём очень серьёзный сетевой хайлоад пишется.
    Ответ написан
    Комментировать
  • По каким материалам изучать Java EE?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Если именно Java EE, то рекомендую книгу Изучаем Java EE 7 (Э. Горнсалвес), написана книга хорошо, перевод вполне сносный. Если хочется чего-то из мира Java EE, то рекомендую Spring и его официальную документацию, которая ничем не хуже книг.
    Ответ написан
    Комментировать
  • Как соотносится сложность написания веб-проектов на asp.net c JavaEE/spring?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Про ASP.net ничего не скажу, но свои пять копеек про JavaEE/Spring вставлю. ИМХО, Java EE имеет порог вхождения выше, чем Spring (особенно мне это так казалось, когда я начинал изучать и то и другое одновременно - Spring 2 и Java EE 5, может, что-то и изменилось за прошедшее время). Spring в чистом виде для абсолютного новичка в Java - тоже не подарок, хотя документация очень хорошая (и я её считаю чуть ли не эталонной). Для полноценного Java EE потребуется сервер приложений аля Glassfish, JBoss, Wildfly и т.д, тогда как веб-приложению на Java EE или Spring нужен только сервлет-контейнер (Tomcat, Jetty или Undertow). Но для Spring Boot поднимать вообще ничего не надо, достаточно только нормальной IDE (NetBeans, IDEA, Eclipse) и всё. Spring Boot идеален для начала изучения Spring, но это не исключает необходимости в более подробном изучении Spring Framework, Security, Data и т.д. в дальнейшем.

    CORE, SE

    одно и то же

    JavaEE - это платформа минимум для небольшой команды разработчиков, и в одного на ней что-то поднимать долго.

    Всё приходит с опытом, но самостоятельно вполне можно разрабатывать проекты.
    Ответ написан
    Комментировать
  • Spring Boot + Html5 video. Как показывать видео, которые расположены в другой директории системы?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Конфигурацией:
    @Configuration
    public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/video/**").addResourceLocations("/path/to/video");
        }
    }


    Таким образом по адресу localhost:8080/video/kotiki.mp4 будет доступно видео /path/to/video/kotiki.mp4 на файловой системе (пример для *nix)
    Ответ написан
    Комментировать
  • Как в JPA следить за двусторонним @OneToMany?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Если сохранить rank (который, как я понял, класса Member), то да, набор members изменится.
    Ответ написан
    2 комментария
  • Актуальны ли еще JSP в Spring MVC проектах?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Каждому своё, никто не запрещает использовать JSP/JSPX, но разработчики Spring рекомендуют использовать что-нибудь более современное, вроде Apache FreeMarker или Thymeleaf.
    Ответ написан
    3 комментария
  • С чего начать изучение Java для web?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Я бы рекомендовал начинать изучение веб-разработки на Java c изучения Spring и ознакомления с основными компонентами Java EE. Ради интереса в дальнейшем можно более подробно ознакомиться с Java EE (ибо Spring и его компоненты сопряжены с Java EE), но за последние годы пути Java EE и Spring разошлись (особенно в плане веба). Плюс сейчас есть проект Spring Boot, который упрощает процесс погружения в Spring.

    Про Java EE скажу, что изучать есть смысл только JPA, т.к. оно активно используется в Spring Data JPA; технологии, связанные с вебом - JSP и JSF, нынче не актуальны, JSP заменяется более вменяемыми библиотеками шаблонирования вроде Thymeleaf и Freemarker, а JSF заменяется самим Spring MVC.

    Насчёт контейнеров: Tomcat (а так же Jetty и Undertow) - веб-контейнер, который поддерживает только Java EE Web Profile, в то время как Glassfish (а так же Payara, Wildfly и JBoss) поддерживает весь стек Java EE, который нужен не всегда.
    uuPbl.jpg

    Мой совет - учи Spring, а Java EE оставь на досуг.
    Ответ написан
    1 комментарий
  • Какой Java-стек выбрать для рекомендательного сервиса?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    1. Spring
    2. Jsoup
    3. Spring (для этого есть RestTemplate) или Apache CXF
    4. Дата - Joda Time, отчёты - Japer Reports или BIRT
    5. Spring for Android


    А так же полезными для обработки данных могут оказаться Spring Integration, Spring Batch и Apache Camel. Спасибо Сергей Горностаев за подсказку
    Ответ написан
    2 комментария
  • Подходящая CMS как основа для сложного сайта?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    CMS/CMF-проектов на Java достаточном много, в том числе и с открытым исходным кодом. В качестве примера можно привести как минимум Hippo и Liferay CE. Можно глянуть эту статью на DZone, а так же соответствующую страницу в англовикипедии.

    Моё мнение - под указанный набор пожеланий лучше разрабатывать проект самостоятельно, так как ни одна CMS/CMF не удовлетворит потребностей на 100%. В данном случае напрашивается стек Spring. CMS хороши на начальном этапе, когда нет окончательного понимания, чего хочется от сайта, и какие задачи сайт будет решать, либо, когда задачи сильно примитивны (вроде простых блогов и сайтов-визиток). А решение выбрать CMS для решения каких-то серьёзных задач рано или поздно приведёт к ситуации, когда CMS не будет удовлетворять все потребности. И тут будут варианты: допиливать CMS под свои нужды (что усложнит разработку и поддержку), подставлять какие-то костыли вроде вашего решения (что тоже усложняет процесс разработки и поддержки), либо страдать и пользоваться тем, что есть.
    Ответ написан
    Комментировать
  • Отвлекаться ли на другие языки программирования?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    1. Углубляйся в то, что уже знаешь. И в C#, и в Java огромное количество направлений развития, обросших большим количеством фреймворков, библиотек и т.д.
    2. Да, в коммерческой/интерпрайз среде это самые востребованные языки.
    3. SQL и диалекты (если будешь углубляться в C#, то T-SQL, если в Java - PL/SQL и PL/pgSQL)

    На будущее, если будешь задаваться этим вопросом ещё раз (а ты будешь), помни, что лучше знать хорошо 2-3 языка программирования (или язык программирования и технологии, связанные с ним), чем плохо знать много языков.
    Ответ написан
    1 комментарий
  • Как соединить Java приложение с приложением на C?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Скажите пожалуйста возможно ли такое , что сайт написан при помощи java, а логика написано например на C. Если да то зачем и как будет происходит это связка?

    Можно, вариантов много, от вызова нативных методов до RMI.

    Если вообще в этом смыл и когда ?

    Смысл может быть в двух случаях - когда надо произвести какие-то архисложные вычисления при помощи CUDA, OpenCL и т.д., либо, когда производительность кода на C значительно быстрее. Но во втором случае логичнее оптимизировать Java-код.

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

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    Иметь отдельное приложение для отслеживания актуальности кэша - дополнительная (ненужная) головная боль.
    Лучше будет реализовать корректное использование кэша:
    • При запросе записи, кэшировать возвращённый результат
    • При изменении/удалении записи, обновлять/удалять кэш
    • При бездействии кэша (невостребованности в течение некоторого времени), удалять


    В Java EE и Spring это всё настраивается аннотациями.
    Ответ написан
    Комментировать
  • Как получить все значения из enum'a спомощью цикла?

    jaxtr
    @jaxtr
    JavaEE/Spring-разработчик
    for (fruit f : fruit.values()) {
                System.out.println(f.getName());
            }
    Ответ написан
    Комментировать