关于IDEA中创建springboot+security+jpa

首先本文章不会分析框架的底层代码只是帮助小白快速搭建项目,因为官方文档都写的明明白白,其中spring Security安全框架可能有部分小白看不懂官方文档

推荐看:spring Security 里面有比较详细的框架分析

废话不多说了进入正题:因为springboot推荐使用Maven(依赖管理框架) 如何使用springboot呢? 在maven的项目目录src/main/java下创建BootApplication类(可以改名)

BootApplication类 (该类是springboot的入口类用于启动springboot):

@EnableTransactionManagement
//用于开启事务注解
@SpringBootApplication
//Springboot的启动入口类
@EnableWebSecurity  //启用web安全
//@Configuration
//@Import({
//    DispatcherServletAutoConfiguration.class,
//    EmbeddedServletContainerAutoConfiguration.class,
//    ErrorMvcAutoConfiguration.class,
//    HttpEncodingAutoConfiguration.class,
//    HttpMessageConvertersAutoConfiguration.class,
//    JacksonAutoConfiguration.class,
//    JmxAutoConfiguration.class,
//    MultipartAutoConfiguration.class,
//    ServerPropertiesAutoConfiguration.class,
//    PropertyPlaceholderAutoConfiguration.class,
//    ThymeleafAutoConfiguration.class,
//    WebMvcAutoConfiguration.class,
//    WebSocketAutoConfiguration.class,
//
//})//用于自定义加载哪些类
public class BootApplication extends SpringBootServletInitializer{

   public static void main(String[] args) {

      SpringApplication.run(BootApplication.class, args);
   }}

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</groupId>
   <artifactId>boot</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>war</packaging>

   <name>boot</name>
   <description>Demo project for Spring Boot</description>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>1.5.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <!--此包是themeleaf模板所需jar包-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>

      <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-springsecurity4</artifactId>
     </dependency>

   <!--web应用所需的包-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>

      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
      </dependency>
          <!--此包用于简化代码可以使用注解自动生成get set等方法-->
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.16.10</version>
      </dependency>
      <!--此包用于对数据库操作基于hibernate-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>

      <!--阿里连接池所需包-->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid</artifactId>
         <version>1.0.25</version>
      </dependency>
      <!--spring安全框架包-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-security</artifactId>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

现在只需要建一个Controller类即可

@RestController
public class Rest {
    @Autowired
    private TestService testService;
    @Secured("ROLE_user")
    @RequestMapping("/v1/{name}")//Rest Api风格
    //@PathVariable用于获取Url上的参数
    public List<User> boot(@PathVariable String name) {

        List<User> list=testService.findAll();
        System.out.println(list.get(0).getUrole());
        String data = "{\"name\":\"张三\"}";
        return list;
    }

}
@RestController是springboot中的新增注解用于开发restful风格api接口 该注解相当于@Controller和@ResponseBody 合用返回的是json格式数据

因为springboot内置了tomcat所以只需要运行BootApplocation类  输入 localhost:8080/v1/name 即可在浏览器中返回{“name”:“张三”}的数据 

是不是相当简单,没有ssh或ssm那么多繁琐的配置文件,也不需要在web中配置mvc,spring


如果你想使用数据库,springboot提供了jpa用于操作数据库(至于什么是jpa,简单说jpa是貌似2006年5月提出的一种ORM持久化规范,它只是一种规范,而我们最常用的hibernate是对jpa的实现,也叫jpa产品) springboot的jpa是基于hibernate的但是他进行了进一步封装,使开发人员更好的与数据库进行交互,首先需要在pom.xml中加入依赖(上面的依赖已经假如,请看上边的pom)  在springboot的配置文件中加入

#配置数据库
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=abc
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

  在创建bean  

//@Getter @Setter 是lok插件中用于帮助自动创建getset方法还有许多注解等用 如果使用@Data
//@Min 是用于字段验证的注解
/*@Data   :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
  @Setter:注解在属性上;为属性提供 setting 方法
  @Getter:注解在属性上;为属性提供 getting 方法
  @Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
  @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
  @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
  @Transient表示属性不与数据库映射
  */
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Getter @Setter private Integer uid;

    @NotBlank(message = "用户名不能为空")
    @Column(name = "username")
    @Getter @Setter private String username;

    @NotBlank(message = "密码不能为空")
    @Column(name = "password")
    @Getter @Setter private String password;

    @NotNull(message = "年龄不能为空")//NotNull用于基本数据类型
    @Min(value =18,message = "年龄必须大于等于18")
    @Column(name = "sage")
    @Getter @Setter private Integer sage;

   /* @NotNull(message = "性别不能为空")*/
    @Column(name = "ssex")
    @NotBlank(message = "性别不为空")//只能用于String
    @Getter @Setter private String ssex;

    @Column(name = "urole")
    @JsonIgnore  //在json序列化时忽略该属性  因为在懒加载时候返回json数据时会出现错误重复加载
    @ManyToMany(cascade = CascadeType.REFRESH,fetch = FetchType.LAZY)//optional设置外键是否可以为空
    @JoinTable(name ="u_r",joinColumns ={@JoinColumn(name = "uid")},inverseJoinColumns = {@JoinColumn(name = "rid")})
    @Getter @Setter private Set<Role> urole=new HashSet<Role>();

}

可能有注意到为什么属性没有get set方法,因为我是用来lombok这个jar,它可以使用注解来自动生成get set用于简化代码

,接着我们新建DaoImpl接口继承JpaRepository(该类已经实现了简单的crud操作我们无需实现Test接口)如果你想自己写sql可以使用@Query注解在方法上按jpa规定的格式创建方法例如下面的findByUsername方法(没有使用@Query是因为这个方法太简单框架帮我们实现了)

public interface Test  extends JpaRepository<User,Long>{
    User findByUsername(String username);
}

在Server层我们直接调用Test接口即可

@Autowired
private Test test;
public List<User> findAll() {
     return test.findAll();
}

在controller中调用test即可实现全查


接下来看如何使用security

原来在ssh中使用security中首先导入导入security的包接着在web中配置代理过滤器

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

在配置security的配置文件

<?xml version="1.0" encoding="UTF-8"?> 
<b:beans xmlns="http://www.springframework.org/schema/security"
   xmlns:b="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不拦截登陆页面 由于从3.1开始不再支持filters="none"-->
<http pattern="/index.jsp" security="none"></http>
<http pattern="/*.js" security="none"></http>
<!-- 开启拦截连  use-expressions="false"用于关闭表达式的权限控制-->
<http auto-config="true" use-expressions="true"  >
  <!--   配置自定义登录页面 -->
  <form-login login-page="/index.jsp" authentication-failure-forward-url="/index.jsp" default-target-url="/success.jsp" />
 
<!--     配置拦截规则 -->
 <intercept-url pattern="/success.jsp" access="hasAnyRole('ROLE_USER','ROLE_admin')"/>
<!--  关闭跨域访问 -->
 <csrf disabled="true"/>
<!--  配置session超时跳转页面  -->
 <session-management invalid-session-url="/index.jsp">
    <!--  最大允许1个用户登录 -->
     <!-- <concurrency-control max-sessions="2" error-if-maximum-exceeded="true"/> -->
 </session-management>
<!--权限不够跳转页面  继承AccessDeniedHandler自定义403页面-->
 <access-denied-handler ref="accessDeniedServletHandler"/>
<!--  注销 -->
 <logout logout-url="/logout" logout-success-url="/index.jsp"  invalidate-session="true" delete-cookies="JSESSIONID"/>
</http>
<authentication-manager alias="authenticationManager">
    <authentication-provider ref="authenticationProvider">
     
 <!-- <user-service >
     配置多个用户
  <user name="user" password="123456" authorities="ROLE_USER" />
  <user name="user1" password="123456" authorities="ROLE_ccc" />  
 </user-service> -->
 </authentication-provider>
 </authentication-manager>
 <!-- 注册authenticationManager用于加载错误信息 -->
<b:bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
 <b:property name="messageSource" ref="messageSource"></b:property>
</b:bean>
<b:bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <b:property name="hideUserNotFoundExceptions" value="false"></b:property>
    <b:property name="userDetailsService" ref="security"></b:property>
</b:bean> 
<!-- 修改spring security的默认国际化资源文件 -->
<b:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<b:property name="basename" value="classpath:messages_zh_CN"></b:property>
</b:bean>
</b:beans>

看到上面的配置文件是不是眼花 没关系springboot与security高度集成 (web配置?不需要,xml?不需要)我们来零配置来使用security

首先我们在BootApplocation上用

@EnableWebSecurity 开启Web

创建一个类继承 WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
//开启方法权限注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   /* @Autowired
    private AuthenticationManager authenticationManager;*///如果想让权限注解生效必须加注入此bean
    @Autowired
    private MyAccessDeniedHandle myAccessDeniedHandle;
    @Autowired
    private MySecurity mySecurity;
    @Override
       public void configure(WebSecurity web) throws Exception {
        //配置静态资源不拦截
        web.ignoring().antMatchers("/static/**", "/**/*.jsp");

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/excep").permitAll()//配置不拦截Url
                .anyRequest().authenticated()
                .and()//相当于结束标签
                .formLogin()
                .loginPage("/")
                .loginProcessingUrl("/action_security")//必须是post请求 如果为Get不生效
                .usernameParameter("username")
                .passwordParameter("password")//配置登陆页面
                .successForwardUrl("/login")
                .failureUrl("/")
                .permitAll()//所有用户都能访问这个页面
                .and()
                .rememberMe()
                .userDetailsService(mySecurity)
                .tokenValiditySeconds(90000)
                .key("abc")
                .rememberMeParameter("rememberMe")
                .rememberMeCookieName("zxl")
                .and()
                .exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandle)//配置403权限页面 myAccessDeniedHandl自定义bean 如果不想自定义可以简单的使用.accessDeniedPage()指定403页面
                .and()
                .logout()
                .invalidateHttpSession(false)
                .permitAll()
                .and()
                .csrf().disable();//关闭csrf 如果开启后注销只能使用post请求用于防止别人伪造logout

    }
    //使用BCrypt密码加密
      @Bean
      public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
      }
    /*  //异常消息加载类
     @Bean
    public ReloadableResourceBundleMessageSource bundleMessageSource(){
        ReloadableResourceBundleMessageSource bundleMessageSource=new ReloadableResourceBundleMessageSource();
        bundleMessageSource.setBasename("classpath:messages_zh_CN");
        return bundleMessageSource;
    }
    @Bean
    //自定义的验证类
    public DaoAuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider daoAuthenticationProvider=new DaoAuthenticationProvider();
       daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
       daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
       daoAuthenticationProvider.setUserDetailsService(mySecurity);
       return daoAuthenticationProvider;
    }
    //加载异常消息
    @Bean
    public ProviderManager providerManager(){
        List<AuthenticationProvider> list=new ArrayList<>();
        list.add(daoAuthenticationProvider());
        ProviderManager providerManager=new ProviderManager(list);
        providerManager.setMessageSource(bundleMessageSource());
        return providerManager;
    }*/
    @Bean
    //自定义的验证类
    public DaoAuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider daoAuthenticationProvider=new DaoAuthenticationProvider();
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);//用于捕捉用户不存在异常
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(mySecurity);
        return daoAuthenticationProvider;
    }



}

该类相当于Security中xml配置文件 如果想使用xml与其混合使用可以使用@Configuration注解来引用xml 

原来使用security的自定义国际化需要配置bean   现在无需配置只需要在maven的resources文件夹创建一个空的messages.properties 在创建一个messages_zh_CN.properties文件夹org/springframework/security/spring-security-core/4.2.3.RELEASE/spring-security-core-4.2.3.RELEASE.jar!/org/springframework/security/messages_zh_CN.properties

中复制到刚才的zh_CN文件夹中即可自定义异常消息

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值