SpringBoot学习(一)

来源:互联网 发布:怎么用手机开淘宝店 编辑:程序博客网 时间:2024/05/29 04:22

SpringBoot简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
Spring Boot特点:
1. 遵循“习惯优于配置”的原则,使用Spring Boot只需很少的配置,大部分时候可以使用默认配置。
2. 项目快速搭建,可无配置整合第三方框架。
3. 可完全不使用xml配置,只使用自动配置和Java config。
4. 内嵌Servlet容器(如Tomcat),应用可用jar包运行(java-jar)。
5. 运行中应用状态的监控。

SpringBoot基础

pom文件

    <!-- springboot的父目录,包含大量默认配置,简化开发 -->    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.2.RELEASE</version>        <relativePath />    </parent>  <properties>    <!-- 编码 -->    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <!-- jdk版本 -->    <java.version>1.8</java.version>  </properties>  <dependencies>    <!-- junit测试依赖包 -->    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <scope>test</scope>    </dependency>    <!-- springboot的web支持 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <!-- springboot测试 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <!-- springboot热启动工具 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-devtools</artifactId>    </dependency>  </dependencies>  <build>    <plugins>        <!-- springboot插件 -->        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins>  </build>

代码示例

    /**     * 用户控制器     */    @RestController    @RequestMapping("/user")    public class UserController {        @Value(value="${aric.secret}")        private String secret;        @Value(value="${aric.number}")        private int id;        @Value(value="${aric.desc}")        private String desc;        @RequestMapping        public String index(){            return "hello world !";        }        //@RequestParam 简单类型的绑定        @RequestMapping("/get")        public Map<String,Object> get(@RequestParam String name){            Map<String,Object> map = new HashMap<String,Object>();            map.put("title", "spring boot");            map.put("name", name);            map.put("secret", secret);            map.put("id", id);            map.put("desc", desc);            return map;        }        // @PathVariable 获取请求url中的动态参数        @RequestMapping("/get/{id}/{name}")        public User getUser(@PathVariable int id, @PathVariable String name){            User user = new User();            user.setId(id);            user.setName(name);            user.setDate(new Date());            return user;        }    }/** * SpringBoot 启动 */@SpringBootApplicationpublic class App {    public static void main( String[] args ){        SpringApplication.run(App.class, args);    }}/** * springboot测试类 */@RunWith(SpringRunner.class)@SpringBootTestpublic class AppTest {    private MockMvc mvc;    @Before    public void setUp(){        this.mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();    }    @Test    public void contextLoads() throws Exception{        RequestBuilder request = get("/user");        mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("hello world !"));        request = get("/user/get").param("name","张三");        mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("{\"author\":\"张三\",\"title\":\"spring boot\"}"));    }}

运行项目:
直接运行main方法或者使用maven命令: spring-boot:run

配置文件

一、配置文件的生效顺序,会对值进行覆盖:
1. @TestPropertySource 注解
2. 命令行参数
3. Java系统属性(System.getProperties())
4. 操作系统环境变量
5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
8. 在@Configuration类上的@PropertySource注解
9. 默认属性(使用SpringApplication.setDefaultProperties指定)

二、配置随机值:
#32位随机字符串
aric.secret=${random.value}
#int类型的随机数字
aric.number=random.int使@Value(value={aric.secret}”)
private String secret;

三、属性占位符
当application.properties里的值被使用时,它们会被存在的Environment过滤,所以你能够引用先前定义的值(比如,系统属性)。

aric.name=www.aric.com`#`属性占位符属性aric.desc=the domain is ${aric.name}

四、Application属性文件,按优先级排序,位置高的将覆盖位置低的
1. 当前目录下的一个/config子目录
2. 当前目录
3. 一个classpath下的/config包
4. classpath根路径(root)

五、服务端口和其他配置
#端口配置:
server.port=8090
#时间格式化
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#时区设置
spring.jackson.time-zone=Asia/BeiJing

六、使用YAML代替Properties

    #配置文件环境配置    spring:      profiles:        active: dev      #jackson      jackson:        date-format: yyyy-MM-dd HH:mm:ss        time-zone: Asia/Chongqing    #端口    server:       port: 8888    ---    spring:      profiles: dev    server:      port: 8080    ---    spring:      profiles: prod    server:      port: 8082    ---    spring:      profiles: test    server:      port: 8081

多环境配置

一. 多环境配置的好处:
1.不同环境配置可以配置不同的参数
2.便于部署,提高效率,减少出错

二. Properties多环境配置
1. 配置激活选项,主配置文件配置这个会优先读取里面的属性覆盖主配置文件的属性
spring.profiles.active=dev
2.添加其他配置文件
application-dev.properties
application-prod.properties
application-test.properties
三.YAML多环境配置
1.配置激活选项
spring:
profiles:
active: dev
2.在配置文件添加三个英文状态下的短横线即可区分
---
spring:
profiles: dev

四.两种配置方式的比较
1.Properties配置多环境,需要添加多个配置文件,YAML只需要一个配件文件
2.书写格式的差异,yaml相对比较简洁,优雅
3.YAML的缺点:不能通过@PropertySource注解加载。如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件。

五.使用对应的环境

java -jar myapp.jar --spring.profiles.active=dev

配置日志

支持日志框架:Java Util Logging, Log4J2 and Logback,默认是使用logback
配置方式:默认配置文件配置和引用外部配置文件配置
一、 默认配置文件配置(不建议使用:不够灵活,对log4j2等不够友好)
# 日志文件名,比如:aric.log,或者是 /var/log/aric.log
logging.file=aric.log
# 日志级别配置,比如: logging.level.org.springframework=DEBUG
logging.level.*=info
logging.level.org.springframework=DEBUG

二、 引用外部配置文件
2.1 logback配置方式:
spring boot默认会加载classpath:logback-spring.xml或者classpath:logback-spring.groovy
使用自定义配置文件,配置方式为:
logging.config=classpath:logback-aric.xml
注意:不要使用logback这个来命名,否则spring boot将不能完全实例化

<?xml version="1.0" encoding="UTF-8"?><configuration>    <!-- 文件输出格式 -->    <property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -| %msg%n" />    <!-- test文件路径 -->    <property name="TEST_FILE_PATH" value="e:/develop/logs" />    <!-- pro文件路径 -->    <property name="PRO_FILE_PATH" value="/develop/aric/logs" />    <!-- 开发环境 -->    <springProfile name="dev">        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">            <encoder>                <pattern>${PATTERN}</pattern>            </encoder>        </appender>        <logger name="com.roncoo.education" level="debug"/>        <root level="info">            <appender-ref ref="CONSOLE" />        </root>    </springProfile>    <!-- 测试环境 -->    <springProfile name="test">        <!-- 每天产生一个文件 -->        <appender name="TEST-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">            <!-- 文件路径 -->            <file>${TEST_FILE_PATH}</file>            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">                <!-- 文件名称 -->                <fileNamePattern>${TEST_FILE_PATH}/info.%d{yyyy-MM-dd}.log</fileNamePattern>                <!-- 文件最大保存历史数量 -->                <MaxHistory>100</MaxHistory>            </rollingPolicy>            <layout class="ch.qos.logback.classic.PatternLayout">                <pattern>${PATTERN}</pattern>            </layout>        </appender>        <root level="info">            <appender-ref ref="TEST-FILE" />        </root>    </springProfile>    <!-- 生产环境 -->    <springProfile name="prod">        <appender name="PROD_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">            <file>${PRO_FILE_PATH}</file>            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">                <fileNamePattern>${PRO_FILE_PATH}/warn.%d{yyyy-MM-dd}.log</fileNamePattern>                <MaxHistory>100</MaxHistory>            </rollingPolicy>            <layout class="ch.qos.logback.classic.PatternLayout">                <pattern>${PATTERN}</pattern>            </layout>        </appender>        <root level="warn">            <appender-ref ref="PROD_FILE" />        </root>    </springProfile></configuration>

2.2 log4j配置
1. 去除logback的依赖包,添加log4j2的依赖包
2. 在classpath添加log4j2.xml或者log4j2-spring.xml(spring boot 默认加载)
3. 自定义配置文件

SpringBoot自定义配置Json转换器

引入fastJson的maven依赖

    <!-- fastJson依赖 -->    <dependency>        <groupId>com.alibaba</groupId>        <artifactId>fastjson</artifactId>        <version>1.2.15</version>    </dependency>

第一种方式,继承WebMvcConfigurerAdapter,重写configureMessageConverters方法。

    public class AricApplication extends WebMvcConfigurerAdapter {        /**         * 自定义json转换器         */        @Override        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {            super.configureMessageConverters(converters);            //1.定义一个converter转换消息对象            FastJsonHttpMessageConverter fjhmc = new FastJsonHttpMessageConverter();            //2.fastjson配置信息            FastJsonConfig jsonConfig = new FastJsonConfig();            //添加配置信息            jsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);            //3.在conver中添加配置信息            fjhmc.setFastJsonConfig(jsonConfig);            //4.将converter添加到converters中            converters.add(fjhmc);        }    }   

第二种方式,使用@Bean注解注入fastjsonHttpMessageConverter。

     /**     * 自定义json转换器     * 使用@Bean注入fastjsonHttpMessageConverter     * @param args     */    @Bean    public HttpMessageConverters fastJsonHttpMessage(){        //1.定义一个converter转换消息对象        FastJsonHttpMessageConverter jsonConverter = new FastJsonHttpMessageConverter();        //2.fastjson配置信息        FastJsonConfig fastJsonConfig = new FastJsonConfig();        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);        jsonConverter.setFastJsonConfig(fastJsonConfig);        HttpMessageConverter<?> converter = jsonConverter;        return new HttpMessageConverters(converter);    }

SpringBoot核心

SpringBoot注解

@SpringBootApplication注解是Spring Boot的核心注解,该注解主要组合了以下注解:
1. @SpringBootConfiguration:这是Spring Boot项目的配置注解,这也是一个组合注解。在Spring Boot项目中推荐使用@ SpringBootConfiguration替代@Configuration。
2. @EnableAutoConfiguration:启用自动配置,该注解会使Spring Boot根据项目中依赖的jar包自动配置项目的配置项。如添加了spring-boot-starter-web的依赖,项目中也就会引入SpringMVC的依赖,Spring Boot就会自动配置tomcat和SpringMVC。
3. @ComponentScan:默认扫描@SpringBootApplication所在类的同级目录以及它的子目录。

关闭自动配置

Spring Boot会根据项目中的jar包依赖,自动做出配置,如果不需要自动配置可手动关闭。

//启动类@SpringBootApplication(exclude={MongoAutoConfiguration.class})//关闭Mongo自动配置public class AricApplication{}

自定义Banner

将banner.txt拷贝到项目的resources目录中可自定义banner。
设置关闭banner

    public class Main {        public static void main( String[] args ) throws SchedulerException, InterruptedException{            SpringApplication app =  new SpringApplication(AricApplication.class);            //设置关闭Banner            app.setBannerMode(Banner.Mode.OFF);            app.run(args);          }    }

全局配置文件

  1. 修改tomcat的端口:server.port=8003
  2. 修改进入DispatcherServlet的规则:server.servlet-path=*.do
  3. 更多配置可参考官方文档

加载xml配置

实际项目中,可能有一些需要必须加载xml配置,可以通过spring提供的@ImportResource来加载xml配置。

    @ImportResource({"classpath:logback-dev.xml","classpath:logback-test.xml"})

日志

Spring Boot对各种日志框架都做了支持,我们可以通过配置来修改默认的日志的配置。上面多配置文件方式可以根据环境选择日志输出方式。
设置日志输出级别:

    logging.level.org.springframework=DEBUG

Spring Boot的自动配置的原理

Spring Boot在进行SpringApplication对象实例化时会加载META-INF/spring.factories文件,将该配置文件中的配置载入到Spring容器。

条件注解


SpringBoot异常处理

一、Spring Boot 将所有的错误默认映射到/error, 实现ErrorController

    @Controller    @RequestMapping(value = "/error")    public class BaseErrorController implements ErrorController {        private static final Logger logger = LoggerFactory.getLogger(BaseErrorController.class);        @Override        public String getErrorPath() {            logger.info("出错,错误异常处理器!");            return "error/error";        }        @RequestMapping        public String error(){            return getErrorPath();        }    }

方法二:添加自定义的错误页面
2.1 html静态页面:在resources/public/error/ 下定义
如添加404页面: resources/public/error/404.html页面,中文注意页面编码
2.2 模板引擎页面:在templates/error/下定义
如添加500页面: templates/error/500.ftl
注意事项:templates/error/ 这个的优先级比较 resources/public/error/高

方法三:使用注解@ControllerAdvice

    /**     * 异常消息处理类     */    @ControllerAdvice    public class GlobalDefaultExceptionHandler {        private static final Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class);        @ExceptionHandler(RuntimeException.class)        @ResponseBody        public String defaultExceptionHandler(HttpServletRequest req,Exception e){            logger.error("自定义异常-RuntimeException");            return "该功能出现异常!";        }        @ExceptionHandler(Exception.class)        @ResponseStatus(HttpStatus.OK)        public ModelAndView doExceptionHandler(HttpServletRequest req,Exception e){            logger.error("自定义异常-Exception");            ModelAndView mav = new ModelAndView();            mav.addObject("aricException", e.getMessage());            mav.setViewName("exception/500");            return mav;        }    }

SpringBoot的Web开发

一.spring boot的web应用开发,是基于spring mvc
二.Spring boot 在spring默认基础上,自动配置添加了以下特性:
1. 包含了ContentNegotiatingViewResolver和BeanNameViewResolver beans。
2. 对静态资源的支持,包括对WebJars的支持。
3. 自动注册Converter,GenericConverter,Formatter beans。
4. 对HttpMessageConverters的支持。
5. 自动注册MessageCodeResolver。
6. 对静态index.html的支持。
7. 对自定义Favicon的支持。
8. 主动使用ConfigurableWebBindingInitializer bean

三.模板引擎的选择
FreeMarker
Thymeleaf
Velocity (1.4版本之后弃用,Spring Framework 4.3版本之后弃用)
Groovy
Mustache
jsp应该尽量避免使用,原因如下:
1. jsp只能打包为:war格式,不支持jar格式,只能在标准的容器里面跑(tomcat,jetty都可以)
2. 内嵌的Jetty目前不支持JSPs
3. Undertow不支持jsps
4. jsp自定义错误页面不能覆盖spring boot 默认的错误页面

模板引擎FreeMarker

一.FreeMarker Maven 依赖

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

二. application.properties 中配置

#freemarker 配置spring.freemarker.allow-request-override=falsespring.freemarker.cache=truespring.freemarker.check-template-location=truespring.freemarker.charset=UTF-8spring.freemarker.content-type=text/htmlspring.freemarker.expose-request-attributes=falsespring.freemarker.expose-session-attributes=falsespring.freemarker.expose-spring-macro-helpers=false

三. 代码示例

    @Controller    @RequestMapping("/templates")    public class TemplatesController {        /**         * 访问ftl文件         * @return         */        @RequestMapping("/hello")        public String hello(Map<String,Object> map){            map.put("name", "curry");            return "hello";        }    }

resource下的templates中hello.ftl文件

    <!DOCTYPE html>    <html>    <head>    <meta charset="UTF-8" />    <title>Insert title here</title>    </head>    <body>        <h1>Hello,${name} !</h1>    </body>    </html>

模板引擎Thymeleaf

一. maven 依赖

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

二. application.properties配置

    #thymeleaf 配置    #开发过程建议关闭缓存    #spring.thymeleaf.cache=false

三. 代码示例

    @Controller    @RequestMapping("/templates")    public class TemplatesController {        /**         * 访问html页面         * @return         */        @RequestMapping("/index")        public String index(Map<String,Object> map){            map.put("name", "james");            return "index";        }    }

resource下的templates中index.html文件

    <!DOCTYPE html>    <html>    <head>    <meta charset="UTF-8" />    <title>Insert title here</title>    </head>    <body>        <h1>Hello,thymeleaf !</h1>        <br/>        welcome <span th:text="${name}"></span>    </body>    </html>

模板引擎jsp

一. maven依赖

<!-- servlet --><dependency>    <groupId>javax.servlet</groupId>    <artifactId>javax.servlet-api</artifactId>    <scope>provided</scope></dependency><!-- jstl --><dependency>    <groupId>javax.servlet</groupId>    <artifactId>jstl</artifactId></dependency><!-- 内嵌的tamcat不支持jsp页面 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-tomcat</artifactId>    <scope>provided</scope></dependency><dependency>    <groupId>org.apache.tomcat.embed</groupId>    <artifactId>tomcat-embed-jasper</artifactId>    <scope>provided</scope></dependency>

二. application.properties配置

#jsp 配置spring.mvc.view.prefix=/WEB-INF/jsp/spring.mvc.view.suffix=.jsp

三. 代码示例

    @Controller    @RequestMapping("/testJsp")    public class JspController {        @RequestMapping("/demo")        public String test(Map<String,Object> map){            map.put("name", "messi");            return "demo";        }    }

webapp下的WEB-INF下的jsp文件中demo.jsp文件

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>jsp demo</title></head><body>    <h2>hello ${name } !</h2></body></html>

资源路径和配置文件

Web开发的自动配置类:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration自动配置ViewResolver。
自动配置静态资源:
如果进入SpringMVC的规则为/时,Spring Boot的默认静态资源的路径为:

#配置进入sprngmvc规则server.servlet-path=/#静态资源路径spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/

进入规则为*.xxx 或者 不指定静态文件路径时,将静态资源放置到webapp下的static目录中即可通过地址访问。

读取外部的配置文件:

    @PropertySource(value = {"classpath:jdbc.properties", "classpath:env.properties",    "classpath:httpclient.properties", "classpath:redis.properties", "classpath:rabbitmq.properties" },     ignoreResourceNotFound = true) //读取外部配置文件,如果不存在则忽略    @ComponentScan(basePackages = "cn.aric") //扫描包    public class AricApplication {

自定义消息转换器

自定义消息转化器,只需要在@Configuration的类中添加消息转化器的@bean加入到Spring容器,就会被Spring Boot自动加入到容器中。

    /**     * 自定义消息转换器     * @return     */    @Bean    public StringHttpMessageConverter stringHttpMessageConverter(){        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));        return converter;    }

SpringBoot整合Servlets、Filters、listeners

自定义Servlet、Filter、Listener

    @WebServlet    public class CustServlet extends HttpServlet {        /**         *          */        private static final long serialVersionUID = 1L;        @Override        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {            System.out.println("servlet get method");            doPost(req,resp);        }        @Override        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {            System.out.println("servlet post method");            resp.getWriter().write("hello world");        }    }    /**     * 自定义过滤器     */    @WebFilter    public class CustFilter implements Filter {        @Override        public void init(FilterConfig filterConfig) throws ServletException {            System.out.println("init filter");        }        @Override        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)                throws IOException, ServletException {            System.out.println("do filter");            chain.doFilter(request, response);        }        @Override        public void destroy() {            System.out.println("destory filter");        }    }    /**     * 自定义监听器     */    @WebListener    public class CustListener implements ServletContextListener {        @Override        public void contextInitialized(ServletContextEvent sce) {            System.out.println("contextInitialized");        }        @Override        public void contextDestroyed(ServletContextEvent sce) {            System.out.println("contextDestroyed");        }    }

方法一:通过注册ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制

    /**     * 注入自定义servlet     * @return     */    @Bean    public ServletRegistrationBean servletRegistrationBean(){        return new ServletRegistrationBean(new CustServlet(),"/aric");    }    /**     * 注入自定义过滤器     * @return     */    @Bean    public FilterRegistrationBean filterRegistrationBean(){        return new FilterRegistrationBean(new CustFilter(), servletRegistrationBean());    }    /**     * 注入自定义监听器     * @return     */    @Bean    public ServletListenerRegistrationBean<CustListener> servletListenerRegistrationBean(){        return new ServletListenerRegistrationBean<CustListener>(new CustListener());    }       

方法二:通过实现 ServletContextInitializer 接口直接注册

    /**     * 实现ServletContainerInitializer实现注册 servlet、filter、listener     */    public class MyServletcontainerInitializer implements ServletContainerInitializer{        @Override        public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {            //注册自定义servlet            ctx.addServlet("custServlet", new CustServlet()).addMapping("/aric");            //注册自定义filter            ctx.addFilter("custFilter", new CustFilter()).                addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true, "custFilter");            //注册自定义listener            ctx.addListener(new CustListener());        }    }

方法三:在 SpringBootApplication 上使用@ServletComponentScan 注解后,直接通过@WebServlet、@WebFilter、@WebListener 注解自动注册

SpringBoot自定义拦截器

    /**     * 自定义拦截器     */    @Component    public class UserLoginHandlerInterceptor implements HandlerInterceptor {        @Override        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)                throws Exception {            System.out.println("登陆拦截器...");            return false;        }        @Override        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,                ModelAndView modelAndView) throws Exception {        }        @Override        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)                throws Exception {        }    }    /**     * 注册自定义拦截器     */    @Configuration    public class SpringMvcConfig extends WebMvcConfigurerAdapter{        //注入用户登陆拦截器        @Autowired        private UserLoginHandlerInterceptor userLoginHandlerInterceptor;        @Override        public void addInterceptors(InterceptorRegistry registry) {            //判断用户是否登陆的拦截器            registry.addInterceptor(userLoginHandlerInterceptor).addPathPatterns("/user/**");        }    }

CORS支持 ###

一、Web开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS等等
CORS与JSONP相比:
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS

二、在spring MVC 中可以配置全局的规则,也可以使用@CrossOrigin注解进行细粒度的配置。

    /**     * Cors全局配置     */    @Configuration    public class CustCorsConfiguration {        @Bean        public WebMvcConfigurerAdapter corsConfigurer(){            return new WebMvcConfigurerAdapter() {                @Override                public void addCorsMappings(CorsRegistry registry) {                    registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8002");                }            };        }    }

或者

    /**     * Cors自定义全局配置     */    @Configuration    public class CustomCorsConfiguration extends WebMvcConfigurerAdapter{        @Override        public void addCorsMappings(CorsRegistry registry) {            registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8002");        }    }

定义方法:

    /**     * api控制器,定义方法     */    @RestController    @RequestMapping("/api")    public class ApiController {        @RequestMapping("/get")        public Map<String,Object> get(@RequestParam String name){            Map<String,Object> map = new HashMap<String,Object>();            map.put("title", "spring boot");            map.put("name", name);            return map;        }    }

细粒度控制:

    /**     * @CrossOrigin 进行Cors细粒度控制     */    @RestController    @RequestMapping(value = "/api",method=RequestMethod.POST)    public class ApiThinController {        @CrossOrigin(origins="http://localhost:8002")        @RequestMapping("/get")        public Map<String,Object> get(@RequestParam String name){            Map<String,Object> map = new HashMap<String,Object>();            map.put("title", "spring");            map.put("name", name);            return map;        }    }

文件上传

一、Spring Boot 默认使用springMVC包装好的解析器进行上传
二、配置

#上传文件配置#默认支持文件上传spring.http.multipart.enabled=true#支持文件写入磁盘spring.http.multipart.file-size-threshold=0#上传文件的临时目录spring.http.multipart.location=#最大支持文件大小spring.http.multipart.max-file-size=1Mb#最大支持请求大小spring.http.multipart.max-request-size=10Mb

三、代码示例
jsp文件夹下的upload.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    <html>    <head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <title>文件上传测试</title>    </head>    <body>        <div>            <form method="post" enctype="multipart/form-data" action="/file/upload">                文件:<input type="file" name="aricFile"><br>                <input type="submit" value="上传">            </form>        </div>    </body>    </html>

上传文件后台处理代码:

    /**     * 文件Contrller     */    @Controller    @RequestMapping("/file")    public class FileController {        private static Logger logger = LoggerFactory.getLogger(FileController.class);        @RequestMapping("/toPage")        public String toPage(){            return "upload";        }        @RequestMapping("/upload")        @ResponseBody        public String upload(@RequestParam("aricFile") MultipartFile file){            if (file.isEmpty()) {                return "文件为空!";            }            //获取文件名            String filename = file.getOriginalFilename();            logger.info("上传文件名称: " + filename);            //获取文件后缀名            String suffixName = filename.substring(filename.lastIndexOf("."));            logger.info("文件后缀名: " + suffixName);            //上传文件地址            String filePath = "e:/develop/temp/";            //文件名称加密            filename = UUID.randomUUID() + suffixName;            //目标文件            File dest = new File(filePath,filename);            //检查是否存在目录            if(!dest.getParentFile().exists()){                dest.getParentFile().mkdirs();            }            try {                file.transferTo(dest);                return "上传成功!";            } catch (IllegalStateException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }            return "上传失败!";        }    }

SpringBoot的数据访问

SpringBoot集成Spring Data Jpa

引入Maven依赖

    <!-- mysql数据库驱动 -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>    </dependency>    <!-- spring-data-jpa -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-data-jpa</artifactId>    </dependency>

实现接口:

    /**     * 继承CrudRepository,具有增删查功能     */    public interface CatDao extends CrudRepository<Cat,Integer>{    }    /**     * 继承PagingAndSortingRepository,具有分页和排序功能     */    public interface CatsDao extends PagingAndSortingRepository<Cat,Integer>{        public Cat findByName(String name);        @Query(" from Cat where age=:a")        public List<Cat> findByAge(@Param("a") Integer age);    }

SpringBoot中使用JdbcTemplate

引入Maven依赖

<!-- jdbc依赖 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-jdbc</artifactId></dependency>

代码:

    @Repository    public class PersonDao {        @Autowired        private JdbcTemplate jdbcTemplate;        public void save(Person person){            if (null != person) {                String sql = "insert into person(name,birth_day,remark) values(";                if (!StringUtils.isEmpty(person.getName())) {                    sql += "'" + person.getName() +  "',";                }                if (null != person.getBirthDay()) {                    sql += person.getBirthDay() + ",";                }                if (!StringUtils.isEmpty(person.getName())) {                    sql += "'" + person.getRemark() + "',";                }                if (sql.endsWith(",")){                    sql = sql.substring(0, sql.length()-1);                }                sql += ")";                jdbcTemplate.execute(sql);            }        }    }

SpringBoot集成MyBatis

引入mybatis和分页工具的Maven依赖

<!-- mybatis依赖 --><dependency>    <groupId>org.mybatis.spring.boot</groupId>    <artifactId>mybatis-spring-boot-starter</artifactId>    <version>1.1.1</version></dependency><!-- mybatis分页工具依赖 --><dependency>    <groupId>com.github.pagehelper</groupId>    <artifactId>pagehelper</artifactId>    <version>4.1.0</version></dependency>

代码配置:

    /**     * MyBatis配置     */    @Configuration    public class MyBatisConfig {        /**         * 注入分页工具         * @return         */        @Bean        public PageHelper pageHelper(){            System.out.println("MyBatisConfig.PageHelper");            PageHelper pageHelper = new PageHelper();            Properties properties = new Properties();            properties.setProperty("offsetAsPageNum", "true");            properties.setProperty("rowBoundsWithCount", "true");            properties.setProperty("reasonable", "true");            pageHelper.setProperties(properties);            return pageHelper;        }    }    /**     * Mapper文件配置     */    @Configuration    @AutoConfigureAfter(MyBatisConfig.class) //保证在MyBatisConfig实例化之后再实例化该类    public class MapperConfig {    }

在启动类上添加注解扫描mapper

    @SpringBootApplication    @MapperScan("cn.aric.*.mapper") //扫描该包下响应的class,Mybatis的持久化类    public class AricApplication{    }

Mapper文件

    /**     * Cat实体的mapper文件     */    public interface CatMapper {        //#{name}命名占位符        @Select("select * from Cat where name = #{name} ")        public List<Cat> getByName(String name);        /**         * 保存操作         * @param cat         */        @Insert("insert into Cat(name) values(#{name})")        @Options(useGeneratedKeys=true,keyProperty="id",keyColumn="id")//设置id自增长        public void save(Cat cat);    }

service略

controller代码

    @RestController    public class MyCatController {        @Autowired        private MyCatService myCatService;        @RequestMapping("/getByName")        public List<Cat> getByName(String name){            //设置分页            PageHelper.startPage(1, 2);            return myCatService.getByName(name);        }    }

事务管理

引入maven依赖:

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

当引入jdbc依赖之后,SpringBoot会自动默认分别注入DataSourceTransactionManager或JpaTransactionManager,所以我们不需要任何额外配置就可以用@Transactional注解进行事务的使用。
@Transactional不仅可以注解在方法上,也可以注解在类上。注解在类上时,此类的所有public方法都是开启事务的。如果类级别和方法级别同时使用@Transactional注解,则使用在方法级别的注解会重载类级别的注解。

SpringBoot整合Druid连接池

引入maven依赖

<!-- druid连接池 --><dependency>    <groupId>com.alibaba</groupId>    <artifactId>druid</artifactId>    <version>1.0.18</version></dependency>

配置文件,只写了部分,详细参考druid资料

    #指定mysql数据库连接消息    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test    spring.datasource.username=root    spring.datasource.password=123    spring.datasource.driverClassName=com.mysql.jdbc.Driver    spring.datasource.max-active=20    spring.datasource.max-idle=8    spring.datasource.min-idle=8    spring.datasource.initial-size=10    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙    spring.datasource.filters=stat,wall,log4j    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录    spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000    # 合并多个DruidDataSource的监控数据    #spring.datasource.useGlobalDataSourceStat=true

配置过滤器

    @SpringBootApplication    public class AricApplication extends SpringBootServletInitializer{        @Override        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {            //设置启动类,用于独立tomcat运行的入口            return builder.sources(AricApplication.class);        }        @Bean        public FilterRegistrationBean fileterRegistrationBean(){            FilterRegistrationBean filter = new FilterRegistrationBean();            filter.setFilter(new WebStatFilter());            filter.setName("druidWebStatFilter");            filter.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*");              filter.addUrlPatterns("/");            return filter;        }        @Bean        public ServletRegistrationBean servletRegistrationBean(){            ServletRegistrationBean servlet = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");            servlet.setName("druidStatViewServlet");            servlet.addInitParameter("restEnable", "false");            return servlet;        }    }

访问url:http://ip地址:端口号/druid/

SpringBoot开发部署

SpringBoot热部署

第一种方式,springloader插件。

    <!-- springloader plugin -->    <plugin>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-maven-plugin</artifactId>        <dependencies>            <!-- springloaded hot deploy -->            <dependency>                <groupId>org.springframework</groupId>                <artifactId>springloaded</artifactId>                <version>1.2.4.RELEASE</version>            </dependency>        </dependencies>        <executions>            <execution>                <goals>                    <goal>repackage</goal>                </goals>                <configuration>                    <classifier>exec</classifier>                </configuration>            </execution>        </executions>    </plugin>

第二种方式,devtools工具。

    <!-- devtools依赖 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-devtools</artifactId>        <optional>true</optional>        <scope>true</scope>    </dependency>    <!-- spring boot devtools plugin -->    <plugin>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-maven-plugin</artifactId>        <configuration>            <!-- fork:没有配置,应用不会restart -->            <fork>true</fork>                   </configuration>    </plugin>

修改tomcat

 /** * 修改tomcat配置 * @return * @throws SchedulerException  * @throws InterruptedException  */@Beanpublic EmbeddedServletContainerFactory servletContainer(){    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();    factory.setPort(8001);    factory.setSessionTimeout(10,TimeUnit.SECONDS);    factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,"/notfound.html"));    return factory;}

将spring-boot-starter-tomcat的范围设置为provided,设置为provided是在打包时会将该包排除,因为要放到独立的tomcat中运行,是不需要的。

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

设置启动配置

集成SpringBootServletInitializer,然后重写configure,将Spring Boot的入口类设置进去。

    @SpringBootApplication    public class AricApplication extends SpringBootServletInitializer{        @Override        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {            //设置启动类,用于独立tomcat运行的入口            return builder.sources(AricApplication.class);        }    }
原创粉丝点击