為什么要使用spring boot羔巢?
- 入門簡單酱固,無需編寫大量的xml文件來配置應(yīng)用
- 內(nèi)置tomcat殴穴,可以生成直接運行的獨立jar文件
- 簡化了spring框架一些繁瑣的開發(fā)方式氏义,提供很多與第三方庫的結(jié)合
使用eclipse新建一個spring boot工程
1.先在eclipse官網(wǎng)下載一個eclipse EE
2.new -> Maven Project
3.填寫項目信息
** 安裝spring boot依賴 **
在pom.xml文件添加一點點東西(保存的時候eclipse會自動下載依賴)隐轩,整個文件如下:
<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>demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
路由配置(輸出hello world)
在默認(rèn)生成的App.java文件修改成下面的代碼:
package demo.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@EnableAutoConfiguration
public class App extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer {
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello World!";
}
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(8000);
}
public static void main( String[] args ){
SpringApplication.run(App.class, args);
}
}
然后我們運行這個文件卦碾,在瀏覽器訪問 http://127.0.0.1:8000/ 即可看到效果铺坞。
我們來分析這個文件做了什么:
其中main方法的代碼就是啟動spring boot應(yīng)用
繼承SpringBootServletInitializer 類實現(xiàn)EmbeddedServletContainerCustomizer 接口編寫customize方法其實是為了修改spring boot應(yīng)用監(jiān)聽的端口
類的兩個修飾器,@Controller是聲明是一個控制器類洲胖,@EnableAutoConfiguration大概是自動加載一些bean
我們輸出Hello World!的方法也有兩個修飾器济榨,@RequestMapping("/")是綁定路由,就是瀏覽器域名端口后面的一段字符串(不包括get參數(shù))绿映,@ResponseBody表示輸出字符串到瀏覽器
也許你會問擒滑,我如何限制get或者post方法請求該方法?
@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseBody
String home() {
return "Hello World!";
}
get請求: RequestMethod.GET
post請求:RequestMethod.POST
put請求: RequestMethod.PUT
delete請求: RequestMethod.DELETE
現(xiàn)在可以限制請求方式了叉弦,但是我想正則匹配路由又該如何處理呢丐一?
@RequestMapping("/test/{a}/*/{b:\\d+}")
@ResponseBody
public String index(@PathVariable int b, @PathVariable String a){
System.out.println(a);
System.out.println(b);
return "test!";
}
請求 http://127.0.0.1:8000/test/cbd/qwe/123 就可以看到效果!
- {XXX}來匹配一個任意字符串
- {xxx:正則表達式}來匹配符合規(guī)則的字符串
- *匹配任意字符串
- @PathVariable 修飾器把{X}的內(nèi)容注入方法的參數(shù)里面
GET淹冰,POST參數(shù)獲取
@RequestMapping("/test")
@ResponseBody
public String test(HttpServletRequest request){
return request.getParameter("a");
}
使用HttpServletRequest 對象的getParameter方法即可獲取get或者post參數(shù)库车,如果參數(shù)不存在則返回null
輸出結(jié)果設(shè)置headers
@RequestMapping(value="/test2", produces="text/plain")
@ResponseBody
public String test2(HttpServletResponse response){
response.setHeader("own", "m");
return "ok";
}
修改content-type需要在修飾器的produces參數(shù)指定
自定義header調(diào)用setHeader方法即可
** 上傳和下載文件 **
先看demo代碼:
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("128KB");
factory.setMaxRequestSize("128KB");
return factory.createMultipartConfig();
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws IOException {
response.setContentType("application/octet-stream");
OutputStream os = response.getOutputStream();
os.write(file.getBytes());
return "upload!";
}
其實很簡單,接收文件只要在參數(shù)加上@RequestParam("file") MultipartFile file樱拴。"file"是post文件的變量名字
下載文件柠衍,先拿輸出response.getOutputStream();洋满。當(dāng)然記得要設(shè)置content-type
模板渲染
這里使用了Thymeleaf模板引擎,其他模板引擎實在搜不出可運行方案珍坊。
第一步添加依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
第二步牺勾,在src/main/resources/templates文件夾編寫模板文件,以.html結(jié)尾
第三步垫蛆,編寫代碼返回模板
package demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Debug {
@RequestMapping("/index")
public String index2(){
return "web";
}
}
注意返回的字符串不需要加上.html禽最。
靜態(tài)文件處理
新建一個類(這里是StaticConfig),繼承WebMvcConfigurerAdapter類袱饭,重寫addResourceHandlers方法,代碼如下:
package demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class StaticConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
resourceHandlerRegistry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(resourceHandlerRegistry);
}
}
靜態(tài)文件放在src/main/resources/static文件夾即可
當(dāng)然為了讓配置生效呛占,我們需要在主類增加注解@ComponentScan("demo.config")虑乖,demo.config換成你新建類的包名
允許跨域請求
只需要往入口類添加下面代碼:
// 允許跨域請求
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
數(shù)據(jù)庫操作
1.第一步當(dāng)然是引入依賴咯,往pom.xml里面添加下面代碼:
<!-- 與數(shù)據(jù)庫操作相關(guān)的依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 使用數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
2.新建一個類用于配置數(shù)據(jù)庫信息
package demo.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
@Configuration
@PropertySource(value="classpath:/demo/config/db_local.properties", ignoreResourceNotFound=true)
public class MyBatisConfig {
@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;
@Value("${db_username}")
private String username;
@Value("${password}")
private String password;
/**
* 創(chuàng)建數(shù)據(jù)源
* @Primary 該注解表示在同一個接口有多個實現(xiàn)類可以注入的時候晾虑,默認(rèn)選擇哪一個疹味,而不是讓@autowire注解報錯
*/
@Bean
//@Primary
public DataSource getDataSource() throws Exception{
Properties props = new Properties();
props.put("driverClassName", this.driverClassName);
props.put("url", this.url);
props.put("username", this.username);
props.put("password", this.password);
return DruidDataSourceFactory.createDataSource(props);
}
/**
* 根據(jù)數(shù)據(jù)源創(chuàng)建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception{
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(ds);//指定數(shù)據(jù)源(這個必須有,否則報錯)
//下邊兩句僅僅用于*.xml文件帜篇,如果整個持久層操作不需要使用到xml文件的話(只用注解就可以搞定)糙捺,則不加
//fb.setTypeAliasesPackage("com.xxx.firstboot.domain");//指定基包
//fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));//指定xml文件位置
return fb.getObject();
}
}
當(dāng)然入口類記得加上掃描(@ComponentScan("demo.config"))
上面數(shù)據(jù)庫密碼那些是讀取了配置文件所以新建一個配置文件(配置文件讀取參考下文說明)
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/map?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
db_username=root
password=root
3.定義操作數(shù)據(jù)表的接口
import java.util.List;
import org.apache.ibatis.annotations.Select;
public interface SpecialtyMapper {
@Select("select * from specialty where province = #{province};")
List<demo.dao.SpecialtyDao> getSpecialtyList(String province);
}
當(dāng)然,我們要在入口類用修飾器掃描這些模型類笙隙,@MapperScan("demo.mapper")
trip.footprint.dao.SpecialtyDao只是一個普通的java類洪灯,用于存儲查詢到的數(shù)據(jù)
package demo.dao;
import java.sql.Timestamp;
public class SpecialtyDao {
private int id;
private String province;
private String title;
private String img;
private Timestamp create_time;
private Timestamp update_time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public Timestamp getCreate_time() {
return create_time;
}
public void setCreate_time(Timestamp create_time) {
this.create_time = create_time;
}
public Timestamp getUpdate_time() {
return update_time;
}
public void setUpdate_time(Timestamp update_time) {
this.update_time = update_time;
}
}
4.在controller中使用
package demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Debug {
@Autowired
private demo.mapper.SpecialtyMapper specialtyMapper;
@RequestMapping("/abc")
@ResponseBody
public String index(){
specialtyMapper.getSpecialtyList("廣東省");
return "ok";
}
}
session放于redis
新建一個java類
package trip.footprint.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@Configuration
@EnableRedisHttpSession
@PropertySource(value = "classpath:/trip/footprint/config/redis_bae.properties")
public class SessionConfig {
@Value("${redisHost}")
private String redisHost;
@Value("${redisPort}")
private int redisPort;
@Value("${redisPassword}")
private String redisPassword;
@Value("${redisDb}")
private int redisDb;
@Bean
public static ConfigureRedisAction configureRedisAction() {
return ConfigureRedisAction.NO_OP;
}
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHost);
factory.setPort(redisPort);
if(redisDb!=-1){
factory.setDatabase(redisDb);
}
if (!redisPassword.equals("")) {
factory.setPassword(redisPassword);
}
return factory;
}
}
然后記得用@ComponentScan("demo.config")來掃描加載
由于代碼讀取配置文件,所以新建一個配置文件
redisHost=127.0.0.1
redisPort=6379
redisPassword=
redisDb=0
controller分離成多個文件
其實每一個controller都是一個java類竟痰,只是類上面有一個修飾器@Controller或者@RestController签钩。當(dāng)然記得用@ComponentScan("xxx.xxx")來掃描加載
依賴注入
首先想把類A作為一個變量注入類B,就需要用修飾器@ComponentScan掃描類A和類B的包坏快,同時類A要在類上面加入修飾器@Component铅檩,類B變量上面添加修飾器 @Autowired。
類A代碼:
package demo.data;
import org.springframework.stereotype.Component;
@Component
public class A {
public String data = "good!";
}
類B代碼:
package demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Debug {
@Autowired
private demo.mapper.SpecialtyMapper specialtyMapper;
@Autowired
private demo.data.A a;
@RequestMapping("/abc")
@ResponseBody
public String index(){
specialtyMapper.getSpecialtyList("廣東省");
return a.data;
}
}
讀取配置文件
讀取配置文件需要使用修飾器莽鸿,@PropertySource(value = "classpath:/trip/footprint/config/redis_bae.properties")昧旨。classpath后面跟著的是配置文件路徑。當(dāng)然入口類記得用@ComponentScan("demo.config")掃描包祥得。加載配置文件兔沃,當(dāng)然要注入變量,用修飾器@Value("${變量名}")即可注入啃沪。代碼如下:
package demo.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
@Configuration
@PropertySource(value="classpath:/demo/config/db_local.properties", ignoreResourceNotFound=true)
public class MyBatisConfig {
@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;
@Value("${db_username}")
private String username;
@Value("${password}")
private String password;
/**
* 創(chuàng)建數(shù)據(jù)源
* @Primary 該注解表示在同一個接口有多個實現(xiàn)類可以注入的時候粘拾,默認(rèn)選擇哪一個,而不是讓@autowire注解報錯
*/
@Bean
//@Primary
public DataSource getDataSource() throws Exception{
Properties props = new Properties();
props.put("driverClassName", this.driverClassName);
props.put("url", this.url);
props.put("username", this.username);
props.put("password", this.password);
return DruidDataSourceFactory.createDataSource(props);
}
/**
* 根據(jù)數(shù)據(jù)源創(chuàng)建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception{
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(ds);//指定數(shù)據(jù)源(這個必須有创千,否則報錯)
//下邊兩句僅僅用于*.xml文件缰雇,如果整個持久層操作不需要使用到xml文件的話(只用注解就可以搞定)入偷,則不加
//fb.setTypeAliasesPackage("com.xxx.firstboot.domain");//指定基包
//fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));//指定xml文件位置
return fb.getObject();
}
}
配置文件如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/map?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
db_username=root
password=root
日志輸出
在src/main/resources新建一個文件,寫入下面內(nèi)容:
logging.file=log/myapp.log
logging.level.org.springframework.web=DEBUG
logging.level.root=DEBUG
代碼輸出日志械哟,代碼如下:
package demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Debug {
@Autowired
private demo.mapper.SpecialtyMapper specialtyMapper;
@Autowired
private demo.data.A a;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/abc")
@ResponseBody
public String index(){
logger.debug("ceshi");
logger.info("對的");
specialtyMapper.getSpecialtyList("廣東省");
return a.data;
}
}
導(dǎo)出成war
其實主要是修改pom.xml疏之,添加下面代碼:
<!-- 打包成war需要 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- end -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
修改pom.xml文件的packaging標(biāo)簽變成<packaging>war</packaging>
然后再用maven build一下: