首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用用户角色将用户保存到DB (JAVA)

用用户角色将用户保存到DB (JAVA)
EN

Stack Overflow用户
提问于 2022-11-11 04:39:33
回答 1查看 44关注 0票数 0

我正在开始我的Java之旅,并在STS中工作,试图将一个新用户保存到MySQL数据库中,但似乎没有任何东西在保存。注册后,应自动赋予新用户用户角色,然后将其保存到SQL数据库中。当我运行应用程序时,一切似乎都运行良好,但是当我尝试创建一个新用户时,我会被重定向回登录页面,而数据库中没有保存任何内容。

这是我的档案:

UserController:

代码语言:javascript
复制
package developer.andy.auth.controllers;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import developer.andy.auth.models.User;
import developer.andy.auth.services.UserService;

@Controller
public class UserController {
    
    private UserService userService;
    
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @RequestMapping("/register")
    public String register(@Valid @ModelAttribute("user") User user) {
        return "register.jsp";
    }
    
    @PostMapping("/process")
    public String process(@Valid @ModelAttribute("user") User user, BindingResult result, Model model, HttpSession session) {
        if(result.hasErrors()) {
            return "register.jsp";
        }
        System.out.println("SAVED USER: "+ user);
        userService.saveWithUserRole(user);
        return "redirect:/login";
    }
    
    @RequestMapping("/login")
    public String login() {
        return "login.jsp";
    }
    
}

application.properties:

代码语言:javascript
复制
spring.datasource.url=jdbc:mysql://localhost:3306/auth
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.mvc.view.prefix=/WEB-INF/

pom.xml:

代码语言:javascript
复制
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>
    </dependencies>

代码语言:javascript
复制
package developer.andy.auth.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class WebSecurityConfiguration {

    // Add BCrypt Bean
    @Bean
    public BCryptPasswordEncoder pwEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            .antMatchers("/css/**", "/js/**", "/register").permitAll()
            .anyRequest()
                .authenticated()
            .and()
                .formLogin().loginPage("/login").permitAll()
            .and()
                .logout().permitAll();

        return http.build();
    }

}

用户模型:

代码语言:javascript
复制
package developer.andy.auth.models;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    
    private String password;
    
    @Transient // allows us to have attributes that are not directly tied to the model
    private String confirm;
    
    @Column(updatable=false) // creates column in DB that cannot be edited
    private Date createdAt;
    
    private Date updatedAt;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private List <Role> roles;
    
    public User() {}

    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

    public String getConfirm() {
        return confirm;
    }

    public void setConfirm(String confirm) {
        this.confirm = confirm;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
    
    @PrePersist
    protected void onCreated() {
        this.createdAt = new Date();
    }
    
    @PreUpdate
    protected void onUpdate() {
        this.updatedAt = new Date();
    }
    
}

榜样:

代码语言:javascript
复制
package developer.andy.auth.models;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import java.util.List;

@Entity
@Table(name = "roles")
public class Role {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    
    @ManyToMany(mappedBy = "roles")
    private List<User> users; // points to User table
    
    public Role() {}

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
    
    
}

用户回购:

代码语言:javascript
复制
package developer.andy.auth.repositories;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import developer.andy.auth.models.User;

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
    User findByUsername(String username);
}

角色回购:

代码语言:javascript
复制
package developer.andy.auth.repositories;

import java.util.List;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import developer.andy.auth.models.Role;

@Repository
public interface RoleRepository extends CrudRepository<Role, String> {
    List<Role> findAll();
    List<Role> findByName(String name);
}

用户服务:

代码语言:javascript
复制
package developer.andy.auth.services;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import developer.andy.auth.models.User;
import developer.andy.auth.repositories.RoleRepository;
import developer.andy.auth.repositories.UserRepository;

@Service
public class UserService {
    
    private UserRepository userRepo;
    private RoleRepository roleRepo;
    private BCryptPasswordEncoder pwEncoder;
    
    public UserService(UserRepository userRepo, RoleRepository roleRepo, BCryptPasswordEncoder pwEncoder) {
        this.userRepo = userRepo;
        this.roleRepo = roleRepo;
        this.pwEncoder = pwEncoder;
    }
    
    // save with user role
    public void saveWithUserRole(User user) {
        user.setPassword(pwEncoder.encode(user.getPassword()));
        user.setRoles(roleRepo.findByName("ROLE_USER"));
        System.out.println("New User: " + user);
        userRepo.save(user);
    }
    
    // save with admin role
    public void saveWithAdminRole(User user) {
        user.setPassword(pwEncoder.encode(user.getPassword()));
        user.setRoles(roleRepo.findByName("ROLE_ADMIN"));
        System.out.println("New Admin: " + user);
        userRepo.save(user);
    }
    
    // find user by username
    public User findByUsername(String username) {
        return userRepo.findByUsername(username);
    }
    
}

register.jsp:

代码语言:javascript
复制
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration Page</title>
</head>
<body>
    <h1>Register!</h1>
    
    <p><form:errors path="user.*"/></p>
    
    <form:form method="POST" action="/process" modelAttribute="user">
        <p>
            <form:label path="username">Username:</form:label>
            <form:input path="username"/>
        </p>
        <p>
            <form:label path="password">Password:</form:label>
            <form:password path="password"/>
        </p>
        <p>
            <form:label path="confirm">Confirm:</form:label>
            <form:password path="confirm"/>
        </p>
<!--         We do not need a csrf token in register bc jstl has already included them for us -->
        <input type="submit" value="Register!"/>
    </form:form>
</body>
</html>

我尝试过检查模型,修改POST URL,并包括一些控制台日志来查找问题,但是即使这样做了,它似乎也不会将任何错误或数据记录到控制台上。这就是输出到控制台中的内容:

代码语言:javascript
复制
2022-11-10 22:20:18.829  INFO 6389 --- [           main] developer.andy.auth.AuthApplication      : No active profile set, falling back to 1 default profile: "default"
2022-11-10 22:20:19.915  INFO 6389 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-11-10 22:20:19.997  INFO 6389 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 70 ms. Found 2 JPA repository interfaces.
2022-11-10 22:20:20.974  INFO 6389 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-11-10 22:20:20.986  INFO 6389 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-11-10 22:20:20.987  INFO 6389 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2022-11-10 22:20:21.323  INFO 6389 --- [           main] org.apache.jasper.servlet.TldScanner     : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2022-11-10 22:20:21.337  INFO 6389 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-11-10 22:20:21.337  INFO 6389 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2405 ms
2022-11-10 22:20:21.552  INFO 6389 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-11-10 22:20:21.607  INFO 6389 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.6.12.Final
2022-11-10 22:20:21.806  INFO 6389 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-11-10 22:20:21.926  INFO 6389 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-11-10 22:20:22.336  INFO 6389 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-11-10 22:20:22.368  INFO 6389 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2022-11-10 22:20:23.373  INFO 6389 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-11-10 22:20:23.383  INFO 6389 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-11-10 22:20:23.869  WARN 6389 --- [           main] .s.s.UserDetailsServiceAutoConfiguration : 


2022-11-10 22:20:24.136  INFO 6389 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@726e29d, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@a1e578f, org.springframework.security.web.context.SecurityContextPersistenceFilter@40239b34, org.springframework.security.web.header.HeaderWriterFilter@811d8d6, org.springframework.security.web.csrf.CsrfFilter@50841932, org.springframework.security.web.authentication.logout.LogoutFilter@3c468360, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@72b6fa98, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1c966488, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@45f6181a, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@707b38a1, org.springframework.security.web.session.SessionManagementFilter@6dcc7696, org.springframework.security.web.access.ExceptionTranslationFilter@3bf52f8f, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@6eae3730]
2022-11-10 22:20:24.197  WARN 6389 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-11-10 22:20:24.775  INFO 6389 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-11-10 22:20:24.789  INFO 6389 --- [           main] developer.andy.auth.AuthApplication      : Started AuthApplication in 6.691 seconds (JVM running for 8.204)
2022-11-10 22:20:36.705  INFO 6389 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-11-10 22:20:36.705  INFO 6389 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-11-10 22:20:36.706  INFO 6389 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms

任何指导都是非常感谢的!

EN

回答 1

Stack Overflow用户

发布于 2022-11-11 21:57:48

我只是想明白为什么我不能将数据保存到DB中。我似乎在roleRepo中指定了不正确的数据类型。

我更改了< String>,将Long>更改为<角色,将Long>更改为引用ID,现在它工作得很好!谢谢大家的帮助!

代码语言:javascript
复制
@Repository
public interface RoleRepository extends CrudRepository<Role, Long> {
    List<Role> findAll();

    List<Role> findByName(String name);
    
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74398082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档