2
respostas

Problemas no carrinho e para finalizar pagamento

Olá!

Eu tenho dois problemas. Um está resolvido, mas eu gostaria de entender o que está acontecendo e descobrir se há algum jeito melhor de resolvê-lo e o outro não consegui descobrir o que é.

Vamos ao resolvido primeiro. Em alguma parte do curso, não sei se ainda no primeiro ou agora no segundo, clicar em comprar o produto e mostrar a tela do carrinho quebrou. No começo, tudo estava funcionando perfeitamente, mas quando fui testar o "finalizar compra" agora no segundo curso, eu recebia NullPointerException ao tentar comprar. Fui olhando tudo, desde a jsp de detalhe até a jsp de itens do carrinho e parecia estar tudo em seu devido lugar. O erro me indicava que um de meus métodos da classe CarrinhoCompras estava retornando nulo. Foi então que eu fiz uns sysout dentro do método add do CarrinhoComprasController e descobri que o add estava funcionando, ou seja, meu Map de itens estava recebendo o item passado pelo detalhe.jsp e o método que estava quebrando também. Fui mais a fundo e então descobri onde estava o cerne do problema: o método getItens da classe CarrinhoCompras. Ele me retornava tanto o elemento adicionado quanto um valor nulo. E no meu entendimento, na hora que o valor nulo chegava no itens.jsp para ser processado, ele quebrava a página. Procurando meios de resolver, descobri isso:

  public Collection<CarrinhoItem> getItens(){
    carrinho.keySet().removeIf(Objects::isNull);
    return carrinho.keySet();
  }

Se eu jogo só o retorno, recebo um conjunto com valor nulo, mas adicionando a linha acima do retorno, eu limpo os valores nulos e a página carrega. Então a dúvida é: por que meu mapa está ficando com um valor nulo lá? Por que a página quebra com esse valor nulo, sendo que eu peço pra ela processar explicitamente o valor que foi passado na requisição? Tem algum meio mais elegante ou melhor de corrigir esse problema?

Ok, esse foi o primeiro. Agora ao segundo.

Não consigo finalizar a compra sem passar pela tela de login. Meu "/pagamentos/" já está com permitAll inclusive antes do instrutor adicionar nesse momento do curso. Esse eu realmente não consegui descobrir.

Os códigos que achei relevantes, coloquei no gist. Segue as páginas pra consulta:

Primeiro

Segundo

Se precisarem de mais alguma coisa, só me dizer. Valeu!

2 respostas

Oi Vini, tudo certo?

Amigo, me tira uma dúvida, o login está sendo solicitado depois de clicar para finalizar, correto?

Acredito que seja por conta que o seu listaProduto.jsp está configurado para só ser exibido com login:

.antMatchers("/produtos/listaProduto").hasRole("ADMIN")

Tenta deixar as configuração assim:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/produtos/form").hasRole("ADMIN")
            .antMatchers("/produtos").hasRole("ADMIN")
            .antMatchers("/produtos/").hasRole("ADMIN")
            .antMatchers("/produtos/**").permitAll()
            .antMatchers("/carrinho/**").permitAll()    
            .antMatchers("/pagamento/**").permitAll()    
            .antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and()
                .formLogin().loginPage("/login").defaultSuccessUrl("/produtos").permitAll()
            .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll() 
                .logoutSuccessUrl("/login");
    }

Dessa forma irá cair na regra ".antMatchers("/produtos/**").permitAll()"

OBS: tinha um monte de texto aqui. Apaguei para caber meu edit 4 corretamente, já que ele que está importando

EDIT 2: esquece, eu tava fazendo o redirect para listaProduto, não listaProdutos :facepalm: só fui perceber agora. Apesar disso, agora tenho outro erro pra resolver, vou dar uma investigada primeiro para ver se descubro o que é.

EDIT 3:

quase me esqueço. E sobre o primeiro problema que descrevi? A solução para o return null do Map é aquela mesma?

EDIT 4:

consegui resolver todas os problemas referentes ao segundo problema que descrevi. Tive que adicionar uma camada a mais de properties ao meu AppWebConfig.java, ficou assim:

@Bean
@Bean
  public MailSender mailSender() {
    JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
    mailSenderImpl.setHost("smtp.gmail.com");
    mailSenderImpl.setUsername("meuemail@gmail.com");
    mailSenderImpl.setPassword("minhasenha");
    mailSenderImpl.setPort(587);

    mailSenderImpl.setJavaMailProperties(mailProperties());
    mailSenderImpl.setSession(mailSession());

    return mailSenderImpl;
  }

  private Session mailSession() {
    Session session = Session.getDefaultInstance(mailProperties(), 
      new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication("meuemail@gmail.com", "minhasenha");
      }
    });

    return session;
  }

  private Properties mailProperties() {
    Properties mailProperties = new Properties();
    mailProperties.put("mail.smtp.auth", true);
    mailProperties.put("mail.smtp.starttls.enable", true);
    mailProperties.put("mail.smtp.host", "smtp.gmail.com");
    mailProperties.put("mail.smtp.socketFactory.port", "465");
    mailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    mailProperties.put("mail.smtp.port", "465");

    return mailProperties;

Além de ativar o acesso de apps menos seguros nas configurações de segurança da conta. Só me restou a dúvida quanto ao Map retornar nulo, isso quebrar a página mesmo eu pedindo explicitamente o valor passado na requisição e se tem outra forma mais elegante de resolver esse problema (que aconteceu comigo, mas não apareceu esse erro durante os vídeos no curso)