zoukankan      html  css  js  c++  java
  • Java Web系列:Spring Boot 基础 Spring Security基本使用

      @OneToOne or @ManyToOne

    Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.lpp.domain.User.roles references an unknown entity: java.util.List
        at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:97) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1786) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1730) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1617) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
        ... 44 common frames omitted

    解决办法:

    将:

    @Entity
    public class User {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//保证存取时有正确的格式
        private Date createDate;
        @ManyToOne
        @JoinColumn(name = "department_id")//user表中使用department_id字段来表示部门id
        @JsonBackReference//防止关系对象的递归访问
        private Department department;
    
        @ManyToOne(cascade = {}, fetch = FetchType.EAGER)
        @JoinTable(name = "user_role",
                joinColumns = {@JoinColumn(name = "user_id")},
                inverseJoinColumns = {@JoinColumn(name = "role_id")})
        //中间表user_role来存在各自的id,以表示它们的对应关系
        private List<Role> roles;

    改为:

    @Entity
    public class User {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//保证存取时有正确的格式
        private Date createDate;
        @ManyToOne
        @JoinColumn(name = "department_id")//user表中使用department_id字段来表示部门id
        @JsonBackReference//防止关系对象的递归访问
        private Department department;
    
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "user_role",
                joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "ID")},
                inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "ID")})
        //中间表user_role来存在各自的id,以表示它们的对应关系
        private List<Role> roles;

    Spring Boot 项目(参考1) 提供了一个类似ASP.NET MVC的默认模板一样的标准样板,直接集成了一系列的组件并使用了默认的配置。使用Spring Boot 不会降低学习成本,甚至增加了学习成本,但显著降低了使用成本并提高了开发效率。如果没有Spring基础不建议直接上手。

    1.基础项目

    这里只关注基于Maven的项目构建,使用Spring Boot CLI命令行工具和Gradle构建方式请参考官网。

    (1)创建项目:

    创建类型为quickstart的Maven项目,删除默认生成的.java文件保持默认的Maven目录即可。

    (2)修改/pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.example</groupId>
        <artifactId>myproject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.1.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    </project>

    (3)添加/src/main/sample/controller/HomeController.java文件:

    package simple.controller;
    
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    public class HomeController {
    
        @RequestMapping("/")
        public String index() {
            return "Hello World!";
        }
    }

    (4)添加/src/main/sample/Application.java文件:

    package simple;
    
    import org.springframework.boot.*;
    import org.springframework.boot.autoconfigure.*;
    import simple.controller.*;
    
    @EnableAutoConfiguration
    public class Application {
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(new Object[] { Application.class, HomeController.class }, args);
        }
    
    }

    在浏览器中输入http://localhost:8080/,即可直接看到"Hello World"运行结果。

    2. 添加数据访问支持

    (1)修改pom,添加spring-boot-starter-data-jpa和h2依赖:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.example</groupId>
        <artifactId>myproject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.1.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
    </project>

    如果需要在控制台查看生成SQL语句,可以添加/src/main/resources/application.properties

    1 spring.h2.console.enabled=true
    2 logging.level.org.hibernate.SQL=debug

    (2)添加实体

    添加User、Role、Category和Post实体。

    User:

    package simple.domain;
    
    import java.util.*;
    
    import javax.persistence.*;
    
    @Entity
    public class User {
        @Id
        @GeneratedValue
        private Long id;
    
        private String userName;
    
        private String password;
    
        private String Email;
    
        @javax.persistence.Version
        private Long Version;
    
        @ManyToMany(cascade = CascadeType.ALL)
        private List<Role> roles = new ArrayList<Role>();
    
        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 getEmail() {
            return Email;
        }
    
        public void setEmail(String email) {
            Email = email;
        }
    
        public List<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(List<Role> roles) {
            this.roles = roles;
        }
    
        public Long getVersion() {
            return Version;
        }
    
        public void setVersion(Long version) {
            Version = version;
        }
    }

    Role:

    package simple.domain;
    
    import java.util.*;
    
    import javax.persistence.*;
    
    @Entity
    public class Role {
        @Id
        @GeneratedValue
        private Long id;
    
        private String roleName;
    
        @ManyToMany(cascade = CascadeType.ALL)
        private List<User> users = new ArrayList<User>();
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getRoleName() {
            return roleName;
        }
    
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
    
        public List<User> getUsers() {
            return users;
        }
    
        public void setUsers(List<User> users) {
            this.users = users;
        }
    }

    Category:

    package simple.domain;
    
    import java.util.*;
    
    import javax.persistence.*;
    
    @Entity
    public class Category {
        @Id
        @GeneratedValue
        private Long id;
    
        private String Name;
    
        @OneToMany
        private List<Post> posts = new ArrayList<Post>();
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return Name;
        }
    
        public void setName(String name) {
            Name = name;
        }
    
        public List<Post> getPosts() {
            return posts;
        }
    
        public void setPosts(List<Post> posts) {
            this.posts = posts;
        }
    }

    Post:

    package simple.domain;
    
    import java.util.*;
    
    import javax.persistence.*;
    
    @Entity
    public class Post {
        @Id
        @GeneratedValue
        private Long id;
    
        private String Name;
    
        private String Html;
    
        private String Text;
    
        private Date CreateAt;
    
        @ManyToOne
        private Category category;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return Name;
        }
    
        public void setName(String name) {
            Name = name;
        }
    
        public String getHtml() {
            return Html;
        }
    
        public void setHtml(String html) {
            Html = html;
        }
    
        public String getText() {
            return Text;
        }
    
        public void setText(String text) {
            Text = text;
        }
    
        public Date getCreateAt() {
            return CreateAt;
        }
    
        public void setCreateAt(Date createAt) {
            CreateAt = createAt;
        }
    
        public Category getCategory() {
            return category;
        }
    
        public void setCategory(Category category) {
            this.category = category;
        }
    }

    (3)添加资源库

    添加UserRepository、RoleRepository、CategoryRepository和PostRepository接口,无需实现。

    UserRepository:

    package simple.repository;
    
    import org.springframework.data.repository.*;
    
    import simple.domain.*;
    
    public interface UserRepository extends CrudRepository<User, Long> {
    
    }

    RoleRepository

    package simple.repository;
    
    import org.springframework.data.repository.*;
    
    import simple.domain.*;
    
    public interface RoleRepository extends CrudRepository<Role, Long> {
    
    }

    CategoryRepository

    package simple.repository;
    
    import org.springframework.data.repository.*;
    
    import simple.domain.*;
    
    public interface CategoryRepository extends CrudRepository<Category, Long> {
    
    }

    PostRepository

    package simple.repository;
    
    import org.springframework.data.repository.*;
    
    import simple.domain.*;
    
    public interface PostRepository extends CrudRepository<User, Long> {
    
    }

    (4)在控制器中注入资源库接口

    package simple.controller;
    
    import org.springframework.beans.factory.annotation.*;
    import org.springframework.web.bind.annotation.*;
    
    import simple.repository.*;
    
    @RestController
    public class HomeController {
    
        private UserRepository userRepository;
        private RoleRepository roleRepository;
        private CategoryRepository categoryRepository;
        private PostRepository postReppository;
    
        @Autowired
        public HomeController(UserRepository userRepository, RoleRepository roleRepository,
                CategoryRepository categoryRepository, PostRepository postReppository) {
            this.userRepository = userRepository;
            this.roleRepository = roleRepository;
            this.categoryRepository = categoryRepository;
            this.postReppository = postReppository;
        }
    
    
        @RequestMapping("/")
        public long index() {
            return userRepository.count();
        }
    }

    使用事务时在方法上应用注解@Transactional

    3.添加验证和授权支持

    (1)添加spring-boot-starter-security依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.example</groupId>
        <artifactId>myproject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.1.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
        </dependencies>
    </project>

    (2)修改Application.java

    package simple;
    
    import org.springframework.boot.*;
    import org.springframework.boot.autoconfigure.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.config.annotation.method.configuration.*;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
    
    import simple.controller.*;
    
    @EnableAutoConfiguration
    @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
    public class Application {
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(new Object[] { Application.class, HomeController.class }, args);
        }
    
        @Bean
        public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() {
            return new MyWebSecurityConfigurer();
        }
    
        public static class MyWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http.csrf().disable();
                http.authorizeRequests().antMatchers("/account**", "/admin**").authenticated();
                http.formLogin().usernameParameter("userName").passwordParameter("password").loginPage("/login")
                        .loginProcessingUrl("/login").successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
                        .and().logout().logoutUrl("/logout").logoutSuccessUrl("/");
                http.rememberMe().rememberMeParameter("rememberMe");
    
            }
        }
    }

    访问http://localhost:8080/account会自动跳转到login登录页。Spring Security的具体使用前文已有所述。

    参考:

    (1)https://github.com/spring-projects/spring-boot

    (2)http://projects.spring.io/spring-boot/

    http://www.cnblogs.com/easygame/p/5122522.html
  • 相关阅读:
    个人永久性免费-Excel催化剂功能第31波-数量金额分组凑数功能,财务表哥表姐最爱
    个人永久性免费-Excel催化剂功能第30波-工作表快捷操作(批量创建、命名、排序、工作表目录)
    个人永久性免费-Excel催化剂功能第29波-追加中国特色的中文相关自定义函数
    发现用System.Net.Mail发邮件(代码附后),附件稍微大一点就会造成程序假死. 有没有什么简单的解决办法呢? 多谢!!
    上传文件 获取文件名 --360浏览器
    js中的json对象和字符串之间的转化
    chosen.jquery.js
    select 后台获取text 并根据text 设置value选中项
    iframe中有ajax,设置iframe自适应高度
    charme浏览器 jquery1.9.1min.js 报脚本错误 无jquery.min.map 文件
  • 原文地址:https://www.cnblogs.com/softidea/p/5122827.html
Copyright © 2011-2022 走看看