最近尝试了一下SpringBoot,发现在controller和service数量相同的时候,比之前用Tomcat启动SpringMVC快了一大半,配置也更少了,很多东西不去重新覆盖设置的话直接会以默认配置启动。

  首先搭建一个同时支持RESTful和传统MVC的服务。完成后的项目目录结构如下:

 

建一个默认Maven工程,新建src/main/resources目录,并添加到classpath。修改pom. ,这里说明一下,以下设定是基于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.spring work.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.1.RELEASE</version>    </parent>    <dependencies>        <!-- Spring Boot Web 依赖 -->        <dependency>            <groupId>org.spring work.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <!-- Spring Boot Test 依赖 -->        <dependency>            <groupId>org.spring work.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <!-- thymeleaf模板 -->        <dependency>            <groupId>org.spring work.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 @SpringBootApplication3 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  ns:th="http://www.thymeleaf.org"> 3 <head> 4 < >Login</ > 5 <  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是 文件在recources目录下的路径

## 数据源配置spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8spring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.jdbc.Driver## Mybatis 配置mybatis.typeAliasesPackage=org.spring.springboot.domainmybatis.mapperLocations=classpath:mapper/*. 

启动类添加对dao层的扫描

1 //Spring Boot 应用的标识2 @SpringBootApplication3 //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类,以及 文件

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 }
<?  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)@Documentedpublic @interface Auth {}

然后添加过滤器LoginInterceptor和一些辅助类,这里拦截之后会进入preHandle方法,如果返回true,则页面会继续执行,否则会被重定向到login页面。验证通过的方法是session里面有username信息,后续可以扩展成通过从缓存中取session信息验证达到分布式服务登录验证。

 1 package graywind.shop.interceptor; 2  3 import org.spring work.beans.factory.annotation.Autowired; 4 import org.spring work.stereotype.Component; 5 import org.spring work.web.method.HandlerMethod; 6 import org.spring work.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 @Component21 public class LoginInterceptor extends HandlerInterceptorAdapter {22     private final static String SESSION_KEY_PREFIX = "session:";23 24     @Autowired25     private UserService userSvc;26 27         public boolean preHandle(HttpServletRequest request, HttpServletResponse response,   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.

 1 package graywind.shop.interceptor; 2  3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.spring work.beans.factory.annotation.Autowired; 6 import org.spring work.context.annotation.ComponentScan; 7 import org.spring work.context.annotation.Configuration; 8 import org.spring work.context.annotation.PropertySource; 9 import org.spring work.web.servlet.config.annotation.CorsRegistry;10 import org.spring work.web.servlet.config.annotation.EnableWebMvc;11 import org.spring work.web.servlet.config.annotation.InterceptorRegistry;12 import org.spring work.web.servlet.config.annotation.WebMvcConfigurerAdapter;13 14 @Configuration  15 @EnableWebMvc  16 @ComponentScan( Packages = "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里面,这个比较常规就不写了。

个人GitHub地址: https://github.com/GrayWind33
收藏 打印