本文所有的代码都在此项目中:https://gitee.com/zhangjunqing/spring-boot/tree/master/springboot-sample
1 搭建最简单spring boot web开发框架:
1.1首先引入maven依赖:
<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.springboot</groupId> <artifactId>springoot</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springoot</name> <url>http://maven.apache.org</url> <!-- 使用spring boot必须有这依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.7.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- 引入web 服务器 tomcat,web框架是 spring web mvc--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
1.2 增加一个启动类:
package com.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication //注意此类的包地址应该是最大的包,这样他就可以自动扫描其下包的所有类.否则也可以(scanBasePackages={"com.springboot.controller"})指定要扫描的包 public class App { public static void main(String[] args) throws Exception { SpringApplication.run(App.class, args); } }
1.3 增加一个controller层
package com.springboot.controller; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/hello") public class HelloController { @RequestMapping("/say") public @ResponseBody String sayHello() { return "hello"; } }
1.4 启动启动类后浏览器输入:http://localhost:8080/hello/say
注意:通过引入spring-boot-starter-web依赖,等同于项目引入了下面的依赖,等于此项目引入了spring,mvc,tomcat和实体类验证器hibernate validator(用于验证实体类的合法性,应用于程序安全加固方面,想学的可以看一下)
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> </dependencies>
项目地址:
https://gitee.com/zhangjunqing/spring-boot
2 增加freemarker支持
2.1 添加依赖
<!-- freemarker支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
2.2 在resources创建templates文件夹下创建freemarker模板文件freemarker.ftl
模板文件内容:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Hello World!</title> </head> <body> <p> welcome ${name} to freemarker! </p> </body> </html>
controller层:
package com.springboot.controller; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/hello") public class HelloController { /** * 整合freemarker模板 * @param map * @return */ @RequestMapping("/freemarker") public String freemarker(Map<String, Object> map) { map.put("name", "topsec"); return "freemarker"; } }
注意:spring boot集成freemarker会默认找resources/templates文件夹的内容。本人没有查找到spring boot直接跳转到html的方法。
3 增加原生servlet,listener,filter的支持
3.1 注意在启动类上添加ServletComponentScan注解,并且指定要扫秒的包名(必须)
package com.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication //注意此类的包地址应该是最大的包,这样他就可以自动扫描其下包的所有类.否则也可以(scanBasePackages={"com.springboot.controller"})指定要扫描的包 @ServletComponentScan({"com.springboot.servlet.servlet","com.springboot.servlet.filter","com.springboot.servlet.listener"})//此注解用于支持原生的servlet public class App { public static void main(String[] args) throws Exception { SpringApplication.run(App.class, args); } }
3.2 @WebFilter(filterName="myFilter",urlPatterns="/*")表示使用原生过滤器,@WebListener原生监听器,@WebServlet(urlPatterns= {"/Myservlet"})表示原生servlet
原生servlet实例代码:
package com.springboot.servlet.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * servlet * @author 76524 * */ @WebServlet(urlPatterns= {"/Myservlet"}) public class MyServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter pw = resp.getWriter(); pw.write("MyServlet"); pw.flush(); pw.close(); } @Override public void init() throws ServletException { System.out.println("初始化********** MyServlet"); } }
原生监听器代码:
package com.springboot.servlet.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * 监听器 * @author 76524 * */ @WebListener public class MyListener implements ServletContextListener{ public void contextInitialized(ServletContextEvent sce) { System.out.println("初始化myListener"); } public void contextDestroyed(ServletContextEvent sce) { System.out.println("銷毀myListener"); } }
原生过滤器代码
package com.springboot.servlet.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; /** * 过滤器 * @author 76524 * */ @WebFilter(filterName="myFilter",urlPatterns="/*") public class MyFilter implements Filter{ public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; System.out.println(req.getRequestURL() + "------>myFilter"); chain.doFilter(request, response); } public void destroy() { // TODO Auto-generated method stub } }
3.3 查看结果
日志如下:
2017-10-14 22:02:45.209 INFO 11236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'myFilter' to urls: [/*] 初始化myListener 2017-10-14 22:02:45.748 INFO 11236 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1a6d8329: startup date [Sat Oct 14 22:02:42 CST 2017]; root of context hierarchy 2017-10-14 22:02:45.866 INFO 11236 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello/freemarker]}" onto public java.lang.String com.springboot.controller.HelloController.freemarker(java.util.Map<java.lang.String, java.lang.Object>) 2017-10-14 22:02:45.873 INFO 11236 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2017-10-14 22:02:45.874 INFO 11236 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2017-10-14 22:02:45.933 INFO 11236 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-14 22:02:45.933 INFO 11236 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-14 22:02:46.028 INFO 11236 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-10-14 22:02:46.354 INFO 11236 --- [ main] o.s.w.s.v.f.FreeMarkerConfigurer : ClassTemplateLoader for Spring macros added to FreeMarker configuration 2017-10-14 22:02:46.650 INFO 11236 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-10-14 22:02:46.780 INFO 11236 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2017-10-14 22:02:46.786 INFO 11236 --- [ main] com.springboot.App : Started App in 5.249 seconds (JVM running for 5.927) 初始化********** MyServlet http://localhost:8080/Myservlet------>myFilter http://localhost:8080/Myservlet------>myFilter
4 通过WebMvcConfigurerAdapter指定拦截器和加载静态文件
4.1 实现WebMvcConfigurerAdapter接口:
package com.springboot.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.springboot.intercepter.MyIntercepter1; import com.springboot.intercepter.MyIntercepter2; @Configuration public class MyConfigurerRegister extends WebMvcConfigurerAdapter { /** * 添加拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyIntercepter1()).addPathPatterns("/**"); registry.addInterceptor(new MyIntercepter2()).addPathPatterns("/**"); super.addInterceptors(registry); } /** * 加载静态文件 */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/image/**") .addResourceLocations("classpath:/image/"); registry.addResourceHandler("/file/**").addResourceLocations("file:D:\\code\\springboot\\springoot\\src\\main\\resources\\image"); //可以直接指定文件路径 super.addResourceHandlers(registry); } }
4.2 定义拦截器
拦截器1:
package com.springboot.intercepter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyIntercepter1 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("-------MyIntercepter1 preHandle"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("-------MyIntercepter1 postHandle"); // TODO Auto-generated method stub } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("-------MyIntercepter1 afterCompletion"); // TODO Auto-generated method stub } }
拦截器2
package com.springboot.intercepter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyIntercepter2 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub System.out.println("-------MyIntercepter2 preHandle"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub System.out.println("-------MyIntercepter2 postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub System.out.println("-------MyIntercepter2 afterCompletion"); } }
4.3 添加静态图片
4.4 运行结果
日志打印:
2017-10-14 23:23:36.147 INFO 16896 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 43 ms
http://localhost:8080/image/my.jpg------>myFilter
http://localhost:8080/image/my.jpg------>myFilter
http://localhost:8080/favicon.ico------>myFilter
http://localhost:8080/image/my.jpg------>myFilter
http://localhost:8080/favicon.ico------>myFilter
http://localhost:8080/image/my.jpg------>myFilter
http://localhost:8080/favicon.ico------>myFilter
http://localhost:8080/image/my.jpg------>myFilter
http://localhost:8080/favicon.ico------>myFilter
注意:
添加静态文件时可以直接指定静态文件的地址。如果不指定静态资源路径则其中默认配置的 /** 映射到 /static (或/public、/resources、/META-INF/resources) ,默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/ ,上面的 static、public、resources 等目录都在 classpath: 下面(如 src/main/resources/static)。也可以通过配置文件来配置,不再举列子。