springboot
春節在家長了幾斤肉,今天開始減肥了(工作了)。19年的第一篇文章,本篇文章將覆蓋springboot所有配置(本人實際工作中所遇到問題以及學習總結),後續將會持續更新!話不多說,直接開始。
詳細配置
注意:本演示全部基於springboot最新版本,現在是2.1.2.RELEASE
,並且所有配置將全部使用yaml格式!
如何配置springboot監聽端口?
- 通過application.yml指定。(推薦)
server:
port: 8080
注意:如果使用server.port=0
,將使用一個隨機端口,可以控制檯查看。
- 指定jvm參數(啓動多個項目調試時推薦使用)
idea中:Edit Configurations -> VM options
運行jar命令:java -Dserver.port=8080 app.jar
[圖片上傳失敗...(image-efdac8-1550224888830)] - 運行
java -jar
命令時指定
如:java -jar app.jar --server.port=8080
- 通過代碼指定:
@Configuration
public class TomcatConfig {
@Bean
@Autowired
public TomcatWebServerFactoryCustomizer factoryCustomizerAutoConfiguration(Environment environment, ServerProperties serverProperties) {
serverProperties.setPort(8888);
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
}
springboot中如何添加filter
- 繼承
Filter
並且將該類作爲一個bean加入spring容器,使用@Order
設置filter順序
@Component
@Order(1000)
public class FirstFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//to do something.
filterChain.doFilter(servletRequest, servletResponse);
}
}
注意!使用這種方式註冊的filter將攔截所有請求,無法指定攔截url。
- 使用
FilterRegistrationBean
類手動註冊一個filter(推薦)
public class SecondFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//to do something.
System.out.println("SecondFilter.doFilter");
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<SecondFilter> secondFilterFilterRegistrationBean() {
FilterRegistrationBean<SecondFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new SecondFilter());
registrationBean.setOrder(10001);
registrationBean.addUrlPatterns("/**");
return registrationBean;
}
}
- 開啓
@WebFilter
掃描。
在啓動類上加上@ServletComponentScan
註解,定義filter如下:
@WebFilter(filterName = "ThridFilter", urlPatterns = "/**")
@Order(1002)
public class ThridFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("ThridFilter.doFilter");
chain.doFilter(req, resp);
}
}
採坑記錄:該方式只在內置web容器下有效(打jar包),如果使用war包,將失效,有興趣的可以看一看@ServletComponentScan
註解說明。
springboot如何添加servlet
- 同上類似,使用
ServletRegistrationBean
@Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new FooServlet(),"/foo/*");
}
如何配置jpa,數據源?
引入jpa依賴,application.yml中添加數據源信息
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: jason
url: jdbc:mysql://localhost:3306/springboot-all-configs?useSSL=false
jpa:
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
採坑記錄1:如果引入jpa但是不定義數據源將會啓動失敗
採坑記錄2:最新版springboot默認mysql驅動爲8.1,自定義參數較多,啓動可能造成數據源初始化失敗,建議降級mysql驅動版本,在pom文件中定義:
[圖片上傳失敗...(image-b8ba24-1550224888830)]
<mysql.version>5.1.47</mysql.version>
生war包運行,部署在weblogic獲取其它servlet容器中
- 將tomcat從maven依賴中去掉,啓動類繼承
SpringBootServletInitializer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
@SpringBootApplication
@ServletComponentScan
public class SpringbootAllConfigsApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringbootAllConfigsApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringBootApplication.class);
}
}
最後將pom文件打包方式修改爲war:
<packaging>war</packaging>
使用idea打包:
使用springboot默認生成的項目mvnw.cmd有什麼用
- 用作生產環境(linux)上沒有maven環境自動下載maven,打包依賴使用
沒卵用,直接刪除
如何設置項目的log level
- 在
application.yml
中指定:
logging:
level:
org:
springframework:
web: debug
- 如果使用logback,添加一個
append
:
<logger name="cn.jsbintask.springbootallconfigs.mapper" level="DEBUG"/>
springboot中訪問配置文件中的配置?
- 使用
@Value
註解
@Value("${server.port}")
private int port;
- 注入
Environment
實例,然後獲取值
@RestController
@RequestMapping
public class PropertiesController {
@Autowired
private Environment environment;
@GetMapping("/path")
public String getPath() {
return environment.getProperty("server.port");
}
}
- 使用
ConfigurationProperties
註解,定義多個屬性值
.yml:
cn:
jsbintask:
name: jason
age: 22
.Properties class:
@ConfigurationProperties(prefix = "cn.jsbintask")
@EnableConfigurationProperties
@Component
@Data
public class JsbintaskProperties {
private String name;
private int age;
}
使用:
@Autowired
private JsbintaskProperties jsbintaskProperties;
如何指定springboot啓動類
-
使用idea指定main class
- 在pom文件中指定啓動類
<properties>
<!-- The main class to start by executing java -jar -->
<start-class>cn.jsbintask.springbootallconfigs.SpringbootAllConfigsApplication</start-class>
</properties>
- 在springboot maven插件中指定:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>cn.jsbintask.springbootallconfigs</mainClass>
</configuration>
</plugin>
</plugins>
</build>
application.yml和bootstrap.yml的區別?
- bootstrap配置文件先於application.yml配置加載,bootstrap配置屬性一般只在
spring cloud
獲取配置服務時使用,所以一般如果不使用spring cloud
的話,優先使用application.yml
.
如何定義rest服務?
- 使用
@ResponseBody
註解配置@RequestMapping註解使用 - 使用新註解
@RestController
配置@XXXMaping(GetMapping)使用。
@RestController
@RequestMapping
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
springboot中如何處理異常?
- 使用
RestControllerAdvice
新註解以及@ExceptionHanlder
處理異常
@RestControllerAdvice
public class ExceptionHandler {
@org.springframework.web.bind.annotation.ExceptionHandler
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
public String hanld(Exception e) {
return "error";
}
}
springboot使用restful服務如何自定錯誤白頁?
當出現錯誤的時候,springboot默認使用一個自定義的錯誤頁面,當使用rest服務時,我們希望自定義返回數據類型。
- 實現ErrorController接口:
@RestController
@RequestMapping
public class CustomErrorController implements ErrorController {
public static final String ERROR_PATH = "/error";
@RequestMapping(path = ERROR_PATH)
public String error() {
return "custom error";
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
如何定義靜態資源訪問映射(圖片)
- 開啓@EnableWebMvc,繼承WebMvcConfigurer類,添加映射
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");
}
}
在static文件夾下新建images文件夾,添加一張圖片,訪問 /images/gril.jpg
:
採坑記錄:上述映射和定位必須一一對應,如改成 registry.addResourceHandler("/static/").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");**
url則需使用 /static/images/gril.jpg,其它靜態資源同樣使用此方法映射。
springboot項目啓動後如何自動運行指定代碼(如初始化)?
- 在main方法後面運行指定service:
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringbootAllConfigsApplication.class, args);
/* way one to init */
HelloController bean = applicationContext.getBean(HelloController.class);
bean.init();
}
- 使用
@EventListener
監聽啓動事件
@Component
public class AppReadyListener {
@EventListener(ApplicationReadyEvent.class)
public void init() {
System.out.println("AppReadyListener.init");
}
}
查看控制檯如下:
- 使用
@PostConstruct
註解
@PostConstruct
public void postConstruct() {
System.out.println("AppReadyListener.postConstruct");
}
- 實現
ApplicationRunner
接口
@Component
public class AppRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("AppRunner.run");
}
}
採坑記錄:方法1在war
環境中不起作用,方法3可能過早執行(這個bean初始化後就執行),方法4,2爲最佳實踐
如何自定義模板引擎(freemarker)
- 添加依賴,修改配置文件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
spring:
freemarker:
template-loader-path: classpath:/templates/
check-template-location: true
charset: UTF-8
enabled: true
suffix: .html
接着添加hello.html在templates文件夾下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>templates</title>
</head>
<body>
<h2>hello from jsbintask blog.</h2>
</body>
</html>
添加一個controller,映射到該模板
@Controller
@RequestMapping("/templates")
public class TemplateController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
啓動項目,訪問/templates/hello
:
springboot如何自定義首頁面,如何自定義視圖
- 同上定義模板引擎
- 實現WebMvcConfigurer接口,添加視圖映射
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//前面爲訪問路徑( '/'即爲主頁面),後面爲視圖模板位置(如本例配置的爲 templates下)。
registry.addViewController("/").setViewName("home");
}
}
配置文件中如何添加數組屬性?
- 使用'-'每行一個屬性
key:
- value1
- value2
- 使用','號隔開每個值
key: value1, value2
使用jpa作數據查詢時,發現實體類的id不能序列化?
這是springboot默認處理了,id不作序列化處理,可以添加如下配置:
@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(User.class);
}
}
採坑記錄:最新版springboot已經默認作了此配置。
springboot修改默認的favicon圖標
- 同上,繼承WebMvcConfigure配置類,添加如下配置:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");
registry.addResourceHandler("/favicon.ico").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/images/favicon.jpg");
}
springboot的api如何編寫單元測試?
建立在已有的springboot項目上,例如helloController,測試 /hello
,編寫測試類:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ServletContext servletContext;
@Test
public void test1() throws Exception{
MvcResult end = mockMvc.perform(requestBuilder("/hello"))
.andExpect(mvcResult -> {
if (mvcResult.getResponse().getStatus() != 200) {
throw new RuntimeException("failed.");
}
})
.andExpect(result -> {
if (!result.getResponse().getContentType().contains("json")) {
throw new RuntimeException("failed");
}
}).andReturn();
System.out.println(end);
}
private RequestBuilder requestBuilder(String uri) {
return MockMvcRequestBuilders.get(URI.create(uri)).accept(MediaType.APPLICATION_JSON_UTF8)
.characterEncoding("UTF-8");
}
}
其中api看名字便知。
springboot如何爲api配置安全訪問?
springboot整合各種消息隊列?
- 參考系列文章:springboot整合各種消息隊列(持續更新中)
未完待續
今天暫時更新到這,此文章會一直更新! 或者你有感興趣的配置,歡迎留言!
總結
未完待續!
例子源碼:https://github.com/jsbintask22/springboot-all-configs-learning.git,歡迎fork,star學習修改。
本文原創地址:https://jsbintask.cn/2019/02/15/springboot/springboot-all-configs/,轉載請註明出處。
如果你覺得本文對你有用,歡迎關注,分享。這裏只有乾貨!