SpringBoot+MyBatis開發環境搭建並實現登錄權限過濾


  最近嘗試了一下SpringBoot,發現在controller和service數量相同的時候,比之前用Tomcat啟動SpringMVC快了一大半,配置也更少了,很多東西不去重新覆蓋設置的話直接會以默認配置啟動。

  首先搭建一個同時支持RESTful和傳統MVC的服務。完成后的項目目錄結構如下:

 

建一個默認Maven工程,新建src/main/resources目錄,並添加到classpath。修改pom.xml,這里說明一下,以下設定是基於1.5.X版本的,由於2.0.0版本開始使用的是Spring5,設置會不一樣。SpringBoot不建議使用JSP,thymeleaf模板是SpringBoot使用的一種前端靜態模板,當然也可以不要前端模板,直接通過前端框架搭建一個。

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>5.1.39</mysql-connector>
    </properties>

    <!-- Spring Boot 啟動父依賴 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

    <dependencies>

        <!-- Spring Boot Web 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Test 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- thymeleaf模板 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- Spring Boot Mybatis 依賴 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>

        <!-- MySQL 連接驅動依賴 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

SpringBoot默認會使用Tomcat容器啟動,要設置一個啟動類

1 //Spring Boot 應用的標識
2 @SpringBootApplication
3 public class App {
4     public static void main(String[] args) {
5         SpringApplication.run(App.class, args);
6     }
7 }

然后是controller層,同樣的如果@RestController則所有請求會自動返回json對象,如果是@Controller則默認會返回頁面模板,如果再加上@ResponseBody則是json對象。

 1 @RestController
 2 public class HelloController {
 3 
 4     @RequestMapping("/HelloWorld")
 5     public String hello() {
 6         return "Hello World!";
 7     }
 8     
 9     @RequestMapping("/HelloBean")
10     public HelloBean hellobean() {
11         HelloBean hello = new HelloBean();
12         hello.setId("123");
13         hello.setPassword("456");
14         hello.setName("小明");
15         return hello;
16     }
17     
18     @RequestMapping("/HelloBean/{id}")
19     public HelloBean hellobean(@PathVariable("id") String id) {
20         HelloBean hello = new HelloBean();
21         hello.setId(id);
22         hello.setPassword("456");
23         hello.setName("小明");
24         return hello;
25     }
26 }
 1 @Controller
 2 public class HtmlController {
 3 
 4     @GetMapping("/login")
 5     public String login(Model model) {
 6         model.addAttribute("success", true);
 7         return "static/login";
 8     }
 9 
10     @GetMapping("/register")
11     public String register(Model model) {
12         return "static/register";
13     }
14 }

 thymeleaf模板的默認路徑是src/main/resources/templates,而首頁會自動設置為/static/index,所以我把所有模板放在了static目錄下,上面controller返回的路徑也就是static/login這樣的格式。添加login.html

 1 <!DOCTYPE HTML>
 2 <html xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4 <title>Login</title>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 6 </head>
 7 <body>
 8     <form class="form-signin" role="form" th:action="@{/user/login}"
 9         th:method="post">
10         <input type="text" class="form-control" placeholder="用戶名"
11             required="required" name="username" /> <input type="password"
12             class="form-control" placeholder="密碼" required="required"
13             name="password" />
14         <button class="btn btn-lg btn-warning btn-block" type="submit">登錄</button>
15         <label class="checkbox"> <input type="checkbox"
16             value="remember-me" /> 記住我
17         </label>
18     </form>
19     <a href="/register">注冊</a>
20     <p th:if="${success} == false">登錄失敗</p>
21     <p th:text="${info}" />
22 </body>
23 </html>

 因為默認設置下模板是不能熱修改啟動的,所以要把它打開,recources目錄下添加文件application.properties

## 頁面動態編譯
spring.thymeleaf.cache=false

 

直接對啟動類運行啟動,效果如下:

 

 

  然后是MyBatis的集成。application.properties再添加設置如下,mybatis.mapperLocations是xml文件在recources目錄下的路徑

## 數據源配置
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

## Mybatis 配置
mybatis.typeAliasesPackage=org.spring.springboot.domain
mybatis.mapperLocations=classpath:mapper/*.xml

啟動類添加對dao層的掃描

1 //Spring Boot 應用的標識
2 @SpringBootApplication
3 //mapper 接口類掃描包配置
4 @MapperScan("graywind.shop.dao")
5 public class App {
6     public static void main(String[] args) {
7         SpringApplication.run(App.class, args);
8     }
9 }

添加Mapper類和Bean類,以及xml文件

1 package graywind.shop.dao;
2 
3 import java.util.List;
4 
5 import graywind.shop.bean.TestBean;
6 
7 public interface TestMapper {
8     public List<TestBean> getTest();
9 }
 1 package graywind.shop.bean;
 2 
 3 public class TestBean {
 4     private String id;
 5     private String txt;
 6 
 7     public String getId() {
 8         return id;
 9     }
10 
11     public void setId(String id) {
12         this.id = id;
13     }
14 
15     public String getTxt() {
16         return txt;
17     }
18 
19     public void setTxt(String txt) {
20         this.txt = txt;
21     }
22 }
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="graywind.shop.dao.TestMapper">
    <select id="getTest" resultType="graywind.shop.bean.TestBean">
        select id,txt from test
    </select>
</mapper>

然后就和以前一樣注入使用

    @Autowired
    private TestMapper testMapper;

    @Override
    public void test() {
        List<TestBean> list = testMapper.getTest();
    }

  接下來做一個權限過濾,我們希望某些頁面是登錄后才能查看的,需要用到過濾器。首先定義@Auth,在類或方法上添加該注解之后,就會被過濾器攔截驗證。

package graywind.shop.interceptor;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 在類或方法上添加@Auth就驗證登錄
 * @author Administrator
 *
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {
}

然后添加過濾器LoginInterceptor和一些輔助類,這里攔截之后會進入preHandle方法,如果返回true,則頁面會繼續執行,否則會被重定向到login頁面。驗證通過的方法是session里面有username信息,后續可以擴展成通過從緩存中取session信息驗證達到分布式服務登錄驗證。

 1 package graywind.shop.interceptor;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Component;
 5 import org.springframework.web.method.HandlerMethod;
 6 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 7 
 8 import graywind.shop.bean.SessionData;
 9 import graywind.shop.service.UserService;
10 
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import java.lang.reflect.Method;
14 import java.util.Optional;
15 
16 import static graywind.shop.interceptor.Constants.MOBILE_NUMBER_SESSION_KEY;
17 import static graywind.shop.interceptor.Constants.SESSION_KEY;
18 import static graywind.shop.interceptor.Constants.USER_CODE_SESSION_KEY;
19 
20 @Component
21 public class LoginInterceptor extends HandlerInterceptorAdapter {
22     private final static String SESSION_KEY_PREFIX = "session:";
23 
24     @Autowired
25     private UserService userSvc;
26 
27         public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
28             throws Exception {
29         String username = (String) request.getSession().getAttribute("username");
30         if (Optional.ofNullable(username).map(String::length).orElse(0) > 0) {
31             return true;
32         }
33 
34         if (!handler.getClass().isAssignableFrom(HandlerMethod.class)) {
35             return true;
36         }
37 
38         final HandlerMethod handlerMethod = (HandlerMethod) handler;
39         final Method method = handlerMethod.getMethod();
40         final Class<?> clazz = method.getDeclaringClass();
41         if (clazz.isAnnotationPresent(Auth.class) || method.isAnnotationPresent(Auth.class)) {
42             if (request.getAttribute(USER_CODE_SESSION_KEY) == null) {
43                 response.sendRedirect(request.getContextPath() + "/login");
44                 return false;
45             } else {
46                 return true;
47             }
48         }
49         return true;
50     }
51 }
package graywind.shop.interceptor;

public interface Constants {
    int MAX_FILE_UPLOAD_SIZE = 5242880;
    String MOBILE_NUMBER_SESSION_KEY = "sessionMobileNumber";
    String USER_CODE_SESSION_KEY = "userCode";
    String SESSION_KEY = "sessionId";
}
package graywind.shop.bean;

public class SessionData {
    private Integer userCode;  
    private String mobileNumber;

    public Integer getUserCode() {
        return userCode;
    }

    public void setUserCode(Integer userCode) {
        this.userCode = userCode;
    }

    public String getMobileNumber() {
        return mobileNumber;
    }

    public void setMobileNumber(String mobileNumber) {
        this.mobileNumber = mobileNumber;
    }
}

最后添加一個MVC設置,代替原先的web.xml

 1 package graywind.shop.interceptor;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.context.annotation.ComponentScan;
 7 import org.springframework.context.annotation.Configuration;
 8 import org.springframework.context.annotation.PropertySource;
 9 import org.springframework.web.servlet.config.annotation.CorsRegistry;
10 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
11 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
12 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
13 
14 @Configuration  
15 @EnableWebMvc  
16 @ComponentScan(basePackages = "graywind.shop.controller")  
17 @PropertySource(value = "classpath:application.properties",  
18         ignoreResourceNotFound = true,encoding = "UTF-8")
19 public class MvcConfig extends WebMvcConfigurerAdapter {
20     private static final Logger logger = LoggerFactory.getLogger(MvcConfig.class);
21     
22     @Autowired  
23     LoginInterceptor loginInterceptor; 
24     
25     @Override  
26     public void addInterceptors(InterceptorRegistry registry) {  
27         // 注冊監控攔截器  
28         registry.addInterceptor(loginInterceptor)  
29                 .addPathPatterns("/**")  
30          .excludePathPatterns("/configuration/ui");  
31   
32     }
33     
34     @Override  
35     public void addCorsMappings(CorsRegistry registry) {  
36         registry.addMapping("/**")  
37                 .allowedOrigins("*")  
38                 .allowedHeaders("*/*")  
39                 .allowedMethods("*")  
40                 .maxAge(120);  
41     }  
42 }

現在就可以在controller層通過@Auth注解來控制權限。最后還要在登錄驗證成功之后將用戶信息寫入到session里面,這個比較常規就不寫了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM