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=
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); } }
全局配置文件
- 修改tomcat的端口:server.port=8003
- 修改进入DispatcherServlet的规则:server.servlet-path=*.do
- 更多配置可参考官方文档
加载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); } }
- springboot学习笔记(一)
- SpringBoot学习篇一
- SpringBoot学习笔记(一)
- SpringBoot学习一
- springBoot 学习(一)
- SpringBoot学习(一)
- springboot学习(一)
- SpringBoot学习笔记一
- Springboot学习一 helloworld
- springboot学习笔记一
- Springboot学习笔记(一)
- SpringBoot学习笔记(一)
- SpringBoot 学习笔记一
- Springboot入门学习(一)
- SpringBoot学习(一)
- springboot学习--《一》
- SpringBoot学习(一)SpringBoot基础入门
- springboot学习记录一、SpringBoot简介
- 从单一WAR到多活, 记述一个创业公司的架构演变
- 一键获取SQL的各种详细信息--脚本
- 访问相册
- 1746. 【usaco 2013 feb Bronze】粉刷栅栏(Painting the Fence)
- 三分查找
- SpringBoot学习(一)
- openCV实现图像的角点检测
- 1027. Colors in Mars (20)
- 大公司的开源项目
- 终于解决了:这个是关于windows下装MYSQL 的驱动,及装完找不到ODBC驱动的解决办法。
- Tensorflow中提供tf.train.ExponentialMovingAverage函数实现(滑动平均模型)
- 面试题55:字符流中第一个不重复的数字
- C++:构造函数与析构函数
- 国内大公司的开源项目