1

I have a problem with the controller, it is returning the whole User Instance while I only need to return attribute which are : "email" and "password".

The problem exists in the public String login () method in the Controller class AuthController (you will find the comment mentioning it on the right line)

Controller

package com.springboot.encuentas.controlador;

import com.springboot.encuentas.library.Encrypt;
import com.springboot.encuentas.model.User;
import com.springboot.encuentas.repository.UserRepository;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpSession;
import javax.transaction.Transactional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

/**
 *
 * @author alfonso
 */
@Controller
public class AuthController {

    @Autowired
    public UserRepository userRepository;

    @GetMapping(value = {"/signup"})
    public String signup(Model model) {
        model.addAttribute("user", new User());
        return "signup";
    }

    @PostMapping(value = {"/signup"})
    @Transactional
    public String signup(@Valid User user, BindingResult result, Model model, HttpSession session) throws Exception {
        if (result.hasErrors()) {
            model.addAttribute("user", user);
            return "signup";
        } else {
            List<User> userUserName = userRepository.findAll().stream()
                    .filter(u -> u.getUsername().equals(user.getUsername()))
                    .collect(Collectors.toList());

            List<User> userEmail = userRepository.findAll().stream()
                    .filter(u -> u.getEmail().equals(user.getEmail()))
                    .collect(Collectors.toList());

            if (userUserName.isEmpty()) {

                if (userEmail.isEmpty()) {
                    Date utilDate = new Date(); //Fecha Actual
                    user.setIsActiva(Boolean.TRUE);
                    user.setIsSuperuser(Boolean.FALSE);
                    user.setPassword(Encrypt.encrypt(user.getPassword()));
                    user.setDateJoined(utilDate);
                    user.setDateJoined(utilDate);
                    userRepository.save(user);

                    Object[] data = {
                        user.getEmail(),
                        user.getFirstName(),
                        user.getIsSuperuser(),
                        user.getLastName(),
                        user.getUsername()
                    };

                    session.setAttribute("usersession", data);

                    return "redirect:/main";
                } else {
                    result.rejectValue("email", "error.user", "Una cuenta existe con este correo.");
                    model.addAttribute("user", user);
                    return "signup";
                }
            } else {
                result.rejectValue("username", "error.user", "Este usuario ya existe.");
                model.addAttribute("user", user);
                return "signup";
            }
        }
    }

    @GetMapping(value = {"/login"})
    public String login(Model model, HttpSession session) {
        Object[] user = (Object[]) session.getAttribute("usersession");
        if (user != null) {
            return "main";
        } else {
            model.addAttribute("user", new User());
            return "login";
        }
    }

    @PostMapping(value = {"/login"})
    @Transactional
    public String login(@Valid User user, BindingResult result, Model model, HttpSession session) throws Exception {
        if (result.hasErrors()) {
            model.addAttribute("user", user); //the problem is here
            return "login";
        } else {
            List<User> userEmail = userRepository.findAll().stream()
                    .filter(u -> u.getEmail().equals(user.getEmail()))
                    .collect(Collectors.toList());
            if (userEmail.isEmpty()) {
                result.rejectValue("email", "error.user", "El email no esta registrado");
                model.addAttribute("user", user); 
                return "login";
            }
        }
        return "login";
    }
}

Repository

package com.springboot.encuentas.repository;

import com.springboot.encuentas.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

}

Class User

package com.springboot.encuentas.model;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

/**
 *
 * @author alfonso
 */
@Entity
@Table(name = "user", schema= "ventas")
@EntityListeners(AuditingEntityListener.class)
public class User implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "users_seq_gen")
    @SequenceGenerator(name = "users_seq_gen", sequenceName = "users_id_seq", allocationSize=1, schema="ventas")
    private Long id;
    @NotBlank(message = "El nombre es requerido")
    private String firstName;
    @NotBlank(message = "El apellido es requerido")
    private String lastName;

    @NotBlank(message = "El email es requerido")
    private String email;

    @CreatedDate
    private Date lastLogin;
    private Boolean isActiva;
    @CreatedDate
    private Date dateJoined;

    @NotBlank(message = "La contraseña es requerida")
    private String password;

    @NotBlank(message = "El usuario es requerido")
    private String username;

    private Boolean isSuperuser;

    public User() {

    }

    public User(String email, String password) {
        this.email = email;
        this.password = password;
    }

    public User(Long id, String firstName, String lastName, String email, Date lastLogin, Boolean isActiva, Date dateJoined, String password, String username, Boolean isSuperuser) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.lastLogin = lastLogin;
        this.isActiva = isActiva;
        this.dateJoined = dateJoined;
        this.password = password;
        this.username = username;
        this.isSuperuser = isSuperuser;
    }



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getLastLogin() {
        return lastLogin;
    }

    public void setLastLogin(Date lastLogin) {
        this.lastLogin = lastLogin;
    }

    public Boolean getIsActiva() {
        return isActiva;
    }

    public void setIsActiva(Boolean isActiva) {
        this.isActiva = isActiva;
    }

    public Date getDateJoined() {
        return dateJoined;
    }

    public void setDateJoined(Date dateJoined) {
        this.dateJoined = dateJoined;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Boolean getIsSuperuser() {
        return isSuperuser;
    }

    public void setIsSuperuser(Boolean isSuperuser) {
        this.isSuperuser = isSuperuser;
    }   
}

Login.html

<div th:replace="~{layout/header :: header}"></div>
<div class="container p-4">
    <div class="row">
        <div class="col-md-4 mx-auto">
            <div class="card text-center">
                <div class="card-header">
                    <h3> Inicio de Session </h3>
                </div>
                <img src="images/logo.png" class="mx-auto w-25" />
                <div class="card-body">
                    <form th:action="@{login}" th:object="${user}" method="POST">
                        <div class="form-group">
                            <input type="email" th:field="*{email}" placeholder="Email" class="form-control">
                            <small class="form-text text-danger" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></small>
                        </div>
                        <div class="form-group">
                            <input type="password" th:field="*{password}" placeholder="Contraseña" class="form-control">
                            <small class="form-text text-danger" th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></small>
                        </div>
                        <div class="form-group">
                            <button class="btn btn-success btn-block">
                                Login
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

<div th:replace="~{layout/footer :: footer}"></div>
mikus
  • 3,042
  • 1
  • 30
  • 40
j3v1t0
  • 41
  • 1
  • 6

2 Answers2

1

You can create UserDTO as follows:

class UserDTO{
    String email;
    String password;
    public UserDTO(String email, String password) {
        this.email = email;
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

Then

public String login(@Valid User user, BindingResult result, Model model, HttpSession session) throws Exception {
    if (result.hasErrors()) {
        UserDTO userDTO = new UserDTO(user.getEmail(), user.getPassword());
        model.addAttribute("user", userDTO);
    }
}
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • No need for that `super();` call in the ctor, and you can get rid of most of that boilerplate code with Lombok. Just use the `@Data` and `@AllArgsConstructor` annotations. – David Conrad Mar 05 '20 at 16:51
  • @DavidConrad - I agree. I forgot to remove `super()`. I've updated my code now. Not sure if OP is using Lombok. – Arvind Kumar Avinash Mar 05 '20 at 16:56
0

i create a new package DTO and i create a new class call it Login. That works for me!

@Controller

   @GetMapping(value = {"/login"})
    public String login(Model model, HttpSession session) {
        model.addAttribute("login", new Login());
        return "login";
    }

    @PostMapping(value = {"/login"})
    @Transactional
    public String LoginDto(@Valid Login login, BindingResult result, Model model, HttpSession session) throws Exception {
        if (result.hasErrors()) {
            model.addAttribute("login", login);
            return "login";
        } else {
            List<User> userEmail = userRepository.findAll().stream()
                    .filter(u -> u.getEmail().equals(login.getEmail()))
                    .collect(Collectors.toList());
            if (userEmail.isEmpty()) {
                result.rejectValue("email", "error.user", "El email no esta registrado");
                model.addAttribute("login", login);
                return "login";
            }
        }
        return "login";
    }

Login Class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.springboot.encuentas.model.dto;

import javax.validation.constraints.NotBlank;

/**
 *
 * @author alfonso
 */
public class Login {
    @NotBlank(message = "El email es requerido")
    private String email;
    @NotBlank(message = "La contraseña es requerida")
    private String password;

    public Login() {
    }

    public Login(String email, String password) {
        this.email = email;
        this.password = password;
    }


    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


}

login.html

<div th:replace="~{layout/header :: header}"></div>
<div class="container p-4">
    <div class="row">
        <div class="col-md-4 mx-auto">
            <div class="card text-center">
                <div class="card-header">
                    <h3> Inicio de Session </h3>
                </div>
                <img src="images/logo.png" class="mx-auto w-25" />
                <div class="card-body">
                    <form th:action="@{login}" th:object="${login}" method="POST">
                        <div class="form-group">
                            <input type="email" th:field="*{email}" placeholder="Email" class="form-control">
                            <small class="form-text text-danger" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></small>
                        </div>
                        <div class="form-group">
                            <input type="password" th:field="*{password}" placeholder="Contraseña" class="form-control">
                            <small class="form-text text-danger" th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></small>
                        </div>
                        <div class="form-group">
                            <button class="btn btn-success btn-block">
                                Login
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

<div th:replace="~{layout/footer :: footer}"></div>
j3v1t0
  • 41
  • 1
  • 6
  • You followed my solution and it worked for you. You can accept my answer so that future visitors can also use the solution confidently. Check https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work to learn how to do it. – Arvind Kumar Avinash May 22 '20 at 11:10