Spring MVC Неверное свойство - PullRequest
0 голосов
/ 12 декабря 2018

Я новичок в Spring, но чтобы продолжить обучение, я работаю над Spring MVC App, но застрял с ошибкой.Я начал с демонстрационного проекта с курса Spring, который я сделал, и у него есть функции входа в систему, выхода из системы и регистрации, именно то, что я хочу сейчас.Что мне не понравилось в этом проекте, так это то, что от пользователя требуется указать имя пользователя и адрес электронной почты для создания новой учетной записи.Поэтому я изменил базовую таблицу базы данных, чтобы у нее было только имя пользователя (которая будет содержать адрес электронной почты), и я избавился от столбца электронной почты.Затем я в основном удалил каждую запись в коде.Все поля электронной почты, все получатели / установщики электронной почты, я удалил его из конструкторов, удалил каждую запись электронной почты на страницах jsp и прошел все контроллеры, нет ничего, что требовало бы свойства электронной почты.Но все же, если я запускаю приложение и нажимаю Зарегистрировать нового пользователя, я получаю:

org.springframework.beans.NotReadablePropertyException: Invalid property 'email' of bean class [com.luv2code.springsecurity.demo.user.CrmUser]: Bean property 'email' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? 

Аналогично, если я пытаюсь войти в систему сейчас, я получаю:

javax.el.PropertyNotFoundException: Property [email] not found on type [com.luv2code.springsecurity.demo.entity.User]

Сейчас,Я мог бы просто сказать, хорошо, забудь об этом, я продолжаю с именем пользователя и электронной почтой, но я хочу понять, что здесь происходит, прежде чем продолжить.Как получилось, например, поиск свойства электронной почты в CrmUser?То же самое относится и к классу сущностей User, поле электронной почты не осталось, так откуда это все-таки?Что я здесь упустил?Мое единственное оставленное предположение состоит в том, что интерфейсам, используемым в конфигурации безопасности для аутентификации, требуется поле электронной почты, но на данный момент я просто должен допустить это.Кто-нибудь может указать мне правильное направление, что я здесь не понимаю?СПАСИБО заранее, дайте мне знать, если потребуется больше кода или даже всего проекта.

Вот моя структура проекта:

project structure

Класс пользователя:

Класс CrmUser:

    @FieldMatch.List({
        @FieldMatch(first = "password", second = "matchingPassword", message = "The password fields must match")
    })
    public class CrmUser {

        //@ValidEmail
        @NotNull(message = "is required")
        @Size(min = 1, message = "is required")
        private String userName;

        @NotNull(message = "is required")
        @Size(min = 1, message = "is required")
        private String password;

        @NotNull(message = "is required")
        @Size(min = 1, message = "is required")
        private String matchingPassword;

        @NotNull(message = "is required")
        @Size(min = 1, message = "is required")
        private String firstName;

        @NotNull(message = "is required")
        @Size(min = 1, message = "is required")
        private String lastName;

    //  @ValidEmail
    //  @NotNull(message = "is required")
    //  @Size(min = 1, message = "is required")
    //  private String email;

        public CrmUser() {

        }
// getters/setters omitted for brevity

Контроллер регистрации:

@Controller
@RequestMapping("/register")
public class RegistrationController {

    @Autowired
    private UserService userService;

    private Logger logger = Logger.getLogger(getClass().getName());

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {

        StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);

        dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
    }   

    @GetMapping("/showRegistrationForm")
    public String showMyLoginPage(Model theModel) {

        theModel.addAttribute("crmUser", new CrmUser());

        return "registration-form";
    }

    @PostMapping("/processRegistrationForm")
    public String processRegistrationForm(@Valid @ModelAttribute("crmUser") CrmUser theCrmUser, BindingResult theBindingResult, Model theModel) {

        String userName = theCrmUser.getUserName();
        logger.info("Processing registration form for: " + userName);

        // form validation
         if (theBindingResult.hasErrors()){
             return "registration-form";
            }

        // check the database if user already exists
        User existing = userService.findByUserName(userName);
        if (existing != null){
            theModel.addAttribute("crmUser", new CrmUser());
            theModel.addAttribute("registrationError", "User name already exists.");

            logger.warning("User name already exists.");
            return "registration-form";
        }
     // create user account                             
        userService.save(theCrmUser);

        logger.info("Successfully created user: " + userName);

        return "registration-confirmation";     
    }
}

DemoSecurityConfig:

@Configuration
@EnableWebSecurity
public class DemoSecurityConfig extends WebSecurityConfigurerAdapter {

    // add a reference to our security data source

    @Autowired
    private UserService userService;

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .antMatchers("/").hasRole("EMPLOYEE")
            .antMatchers("/leaders/**").hasRole("MANAGER")
            .antMatchers("/systems/**").hasRole("ADMIN")
            .and()
            .formLogin()
                .loginPage("/showMyLoginPage")
                .loginProcessingUrl("/authenticateTheUser")
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
            .and()
            .logout().permitAll()
            .and()
            .exceptionHandling().accessDeniedPage("/access-denied");

    }

    //beans
    //bcrypt bean definition
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //authenticationProvider bean definition
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService); //set the custom user details service
        auth.setPasswordEncoder(passwordEncoder()); //set the password encoder - bcrypt
        return auth;
    }

}

UserDaoImpl:

@Repository
public class UserDaoImpl implements UserDao {

    // need to inject the session factory
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public User findByUserName(String theUserName) {
        // get the current hibernate session
        Session currentSession = sessionFactory.getCurrentSession();

        // now retrieve/read from database using username
        Query<User> theQuery = currentSession.createQuery("from User where userName=:uName", User.class);
        theQuery.setParameter("uName", theUserName);
        User theUser = null;
        try {
            theUser = theQuery.getSingleResult();
        } catch (Exception e) {
            theUser = null;
        }

        return theUser;
    }

    @Override
    public void save(User theUser) {
        // get current hibernate session
        Session currentSession = sessionFactory.getCurrentSession();

        // create the user ... finally LOL
        currentSession.saveOrUpdate(theUser);
    }

}

UserServiveImpl:

@Service
public class UserServiceImpl implements UserService {

    // need to inject user dao
    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public User findByUserName(String userName) {
        // check the database if the user already exists
        return userDao.findByUserName(userName);
    }

    @Override
    @Transactional
    public void save(CrmUser crmUser) {
        User user = new User();
         // assign user details to the user object
        user.setUserName(crmUser.getUserName());
        user.setPassword(passwordEncoder.encode(crmUser.getPassword()));
        user.setFirstName(crmUser.getFirstName());
        user.setLastName(crmUser.getLastName());
        //user.setEmail(crmUser.getEmail());

        // give user default role of "employee"
        user.setRoles(Arrays.asList(roleDao.findRoleByName("ROLE_EMPLOYEE")));

         // save user in the database
        userDao.save(user);
    }

    @Override
    @Transactional
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        User user = userDao.findByUserName(userName);
        if (user == null) {
            throw new UsernameNotFoundException("Invalid username or password.");
        }
        return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(),
                mapRolesToAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
        return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
    }
}

registration-form.jsp:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<!doctype html>
<html lang="en">

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="Vogt Pferdedeckenreinigung">
        <meta name="author" content="MB">

        <title>Pferdedeckenwäscherei und Reparaturservice Vogt - Registrierung</title>

        <!-- Get local CSS files -->
        <spring:url value="/resources/css/styles.css" var="mainCss" />
        <spring:url value="/resources/css/bootstrap.min.css" var="bootstrapCss" />

        <!-- Get local JS files -->
        <spring:url value="/resources/js/bootstrap.min.js.download" var="bootstrapJS" />
        <spring:url value="/resources/js/jquery-3.3.1.slim.min.js.download" var="jqueryJS" />
        <spring:url value="/resources/js/popper.min.js.download" var="popperJS" />

        <link href="${mainCss}" rel="stylesheet" />
        <link href="${bootstrapCss}" rel="stylesheet" />

        <script src="${bootstrapJS}"></script>
        <script src="${jqueryJs}"></script>
        <script src="${popperJS}"></script>

    </head>

    <body class="text-center">

    <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
      <header class="masthead mb-auto">
        <div class="inner">
          <h3 class="masthead-brand">Vogt</h3>
          <nav class="nav nav-masthead justify-content-center">
            <a class="nav-link" href="${pageContext.request.contextPath}/.">Bestellung</a>
            <a class="nav-link active" href="${pageContext.request.contextPath}/register/showRegistrationForm">Neukunde</a>
            <a class="nav-link" href="https://www.pferdedeckenwaescherei-vogt.de/kontakt">Kontakt</a>
          </nav>
        </div>
      </header>

      <main role="main" class="inner cover">
          <body class="text-center">
                            <form:form action="${pageContext.request.contextPath}/register/processRegistrationForm" 
                               modelAttribute="crmUser" class="form-signin">
                        <img class="mb-4" src="<spring:url value="/resources/img/logo.png"/>" alt="" width="559" height="152">
                        <h1 class="h3 mb-3 font-weight-normal">Registrieren</h1>
                        <div class="form-group">
                            <div class="col-xs-15">
                                <div>

                                    <!-- Place for messages: error, alert etc ... -->
                        <div class="form-group">
                            <div class="col-xs-15">
                                <div>

                                    <!-- Check for registration error -->
                                    <c:if test="${registrationError != null}">

                                        <div class="alert alert-danger col-xs-offset-1 col-xs-10">
                                            ${registrationError}
                                        </div>

                                    </c:if>

                                </div>
                            </div>
                        </div>
                        </div>
                        </div>
                        </div>
                        <!-- User name -->
                            <form:errors path="userName" class="error" />
                            <form:input path="userName" placeholder="Username" class="form-control"/>

                        <!-- Password -->
                            <form:errors path="password" class="error" />
                            <form:password path="password" placeholder="password (*)" class="form-control" />
                        <!-- Confirm Password -->
                            <form:errors path="matchingPassword" class="error" />
                            <form:password path="matchingPassword" placeholder="confirm password (*)" class="form-control" />
                        <!-- First name -->
                            <form:errors path="firstName" class="error" />
                            <form:input path="firstName" placeholder="first name (*)" class="form-control" />
                        <!-- Last name -->
                            <form:errors path="lastName" class="error" />
                            <form:input path="lastName" placeholder="last name (*)" class="form-control" />
                        <!-- Email 
                            <form:errors path="email" class="error" />
                            <form:input path="email" placeholder="email (*)" class="form-control" />
                        -->
                        <!-- Login/Submit Button -->
                        <div class="checkbox mb-3">
                            <label>
                                <input type="checkbox" value="remember-me"> Anmeldedaten speichern
                            </label>
                        </div>
                        <button class="btn btn-lg btn-primary btn-block" type="submit">Registrieren</button>

                    </form:form>
      </main>
    </div>


    </body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...