一 SpringBoot简介

SpringBoot是Spring框架的一个新子项目 用于创建Spring4.0项目 它的开发始于2013年 2014年4月发布1.0.0版本 它可以自动配置Spring的各种组件 并不依赖代码生成和XML配置文件 SpringBoot也提供了对于常见场景的推荐组件配置 SpringBoot可以大大提升使用Spring框架时的开发效率 使用SpringBoot可以轻松的创建独立运行的程序 非常容易构建独立的服务组件 是实现分布式架构 微服务架构利器

二 SpringBoot优点

1. 轻松创建独立的Spring应用程序

2. 内嵌Tomcat Jetty等web容器 不需要部署WAR文件

3. 提供一系列的Starter 来简化的Maven配置 不需要添加很多依赖

4. 开箱即用 尽可能自动配置Spring

三 SpringBoot初体验

1. 新建一个Maven项目 注意不需要webapp文件夹及子文件夹和web.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hy.springboot</groupId>
<artifactId>springboot-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent> <!-- 定义依赖版本号 -->
<properties>
<mysql-connector-java.version>8.0.11</mysql-connector-java.version>
<druid.version>1.1.10</druid.version>
<mybatis-spring-boot-starter.version>2.1.3</mybatis-spring-boot-starter.version>
<pagehelper-spring-boot-starter.version>1.3.0</pagehelper-spring-boot-starter.version>
</properties> <!-- 管理jar版本号 -->
<dependencyManagement>
<dependencies>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
</dependencies> <build>
<!-- 允许mybatis的mapper.java和mapper.xml在同一目录 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources> <!-- 打包名称 -->
<finalName>one</finalName>
<plugins>
<!-- 编译 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- spring boot -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.hy.springboot.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

sql

-- 用户表
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户id',
username VARCHAR(32) COMMENT '用户名',
money DOUBLE COMMENT '用户余额'
); INSERT INTO user VALUES (1, '曹操', 8000);
INSERT INTO user VALUES (2, '孙权', 8000);
INSERT INTO user VALUES (3, '刘备', 8000);
INSERT INTO user VALUES (4, '诸葛亮', 5000);
INSERT INTO user VALUES (5, '司马懿', 5000);
INSERT INTO user VALUES (6, '张飞', 0);
INSERT INTO user VALUES (7, '关羽', 0);
INSERT INTO user VALUES (8, '马超', 1000);
INSERT INTO user VALUES (9, '黄忠', 1000);
INSERT INTO user VALUES (10, '赵云', 3000);

2. 创建配置文件 resources/application.yml

spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_hy?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
max-active: 20
min-idle: 5
servlet:
multipart:
max-file-size: 5Mb
max-request-size: 10MB
mybatis:
type-aliases-package: com.hy.springboot.model
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
server:
port: 8081
servlet:
context-path: /

3. 创建实体类 com.hy.springboot.model.User com.hy.springboot.model.PageWrapper com.hy.springboot.model.HttpError

public class User implements Serializable {

    private Integer id;
private String username;
private Double money; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Double getMoney() {
return money;
} public void setMoney(Double money) {
this.money = money;
} @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", money=" + money +
'}';
}
}
public class PageWrapper implements Serializable {

    private Long total;
private List list; public PageWrapper() {} public PageWrapper(Long total, List list) {
this.total = total;
this.list = list;
} public Long getTotal() {
return total;
} public void setTotal(Long total) {
this.total = total;
} public List getList() {
return list;
} public void setList(List list) {
this.list = list;
}
}
public class HttpError extends Exception {

    private int code;
private String message; public HttpError() {} public HttpError(int code, String message) {
this.code = code;
this.message = message;
} public int getCode() {
return code;
} public void setCode(int code) {
this.code = code;
} @Override
public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} @Override
public String toString() {
return "HttpError{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}

4. 自定义文件上传实现类 com.hy.springboot.resolver.PostAndPutMultipartResolver 解决客户端(android ios...) PUT提交文件表单异常

public class PostAndPutMultipartResolver extends StandardServletMultipartResolver {

    @Override
public boolean isMultipart(HttpServletRequest request) {
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
return StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/");
}
return false;
}
}

5. 配置文件上传实现类 com.hy.springboot.config.MultipartResolverConfig

@Configuration
public class MultipartResolverConfig { @Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
return new PostAndPutMultipartResolver();
}
}

6. 创建拦截器 com.hy.springboot.interceptor.Interceptor

public class Interceptor implements HandlerInterceptor {

    // Controller执行前调用此方法
// 返回true继续执行 返回false中止执行
// 这里可加入登录校验 权限拦截等
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(" ========== preHandle ========== ");
// 放行
return true;
} // Controller执行后 且未返回视图前 调用此方法
// 这里可在返回用户前对模型数据进行加工处理 比如这里加入公用信息以便页面显示
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {} // Controller执行后 且视图返回后 调用此方法
// 这里可得到执行Controller时的异常信息
// 这里可记录操作日志
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
}

7. 配置拦截器 com.hy.springboot.config.InterceptorConfig

@Configuration
public class InterceptorConfig implements WebMvcConfigurer { @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new Interceptor()).addPathPatterns("/**"); //拦截所有
}
}

8. 配置异常处理器 com.hy.springboot.exception.HttpErrorResolver

@ControllerAdvice
public class HttpErrorResolver { @ExceptionHandler(RuntimeException.class)
@ResponseBody
public HttpError resolveException(Exception e) {
HttpError error = e instanceof HttpError ? (HttpError) e : new HttpError(-1, "未知异常");
return error;
}
}

9. 配置数据源 com.hy.springboot.config.DruidConfig

@Configuration
public class DruidConfig { @Bean
@ConfigurationProperties(prefix = "spring.datasource") //将application.yml配置文件中前缀为spring.datasource的属性注入到DruidDataSource同名参数中
public DataSource dataSource() {
return new DruidDataSource();
}
}

10. 配置AOP com.hy.springboot.aop.LogAspect

@Component
@Aspect
public class LogAspect { /**
* 声明公共切入点
* expression(表达式): 切点表达式
* * com.hy.springboot.controller..*.*(..)
* * = 任意返回值
* com.hy.springboot.controller. = com.hy.springboot.controller包和所有子包
* .*.* = .任意类.任意方法名
* (..) = 任意参数
*/
@Pointcut("execution(* com.hy.springboot.controller..*.*(..))")
public void pointcut() {} /**
* 前置通知 在方法执行前执行 如果通知抛出异常 阻止方法运行
* @param joinPoint 连接点
*/
@Before("pointcut()")
public void before(JoinPoint joinPoint) {
System.out.println("前置通知 JoinPoint = " + joinPoint.toString());
// 请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String url = request.getRequestURL().toString();
String method = request.getMethod();
System.out.println("url = " + url);
System.out.println("method = " + method);
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = enu.nextElement();
System.out.println(name + "=" + request.getParameter(name));
}
} /**
* 后置通知 方法正常返回后执行 可以获得方法返回值 如果方法中抛出异常 通知无法执行
* @param joinPoint 连接点
* @param ret 方法返回值
*/
@AfterReturning(value = "pointcut()", returning = "ret")
public void afterReturning(JoinPoint joinPoint, Object ret) {
System.out.println("后置通知 ret = " + ret + " JoinPoint = " + joinPoint.toString());
}
}

11. 配置启动器 com.hy.springboot.Application

@SpringBootApplication
@MapperScan("com.hy.springboot.mapper")
public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

12. 创建mapper接口 com.hy.springboot.mapper.UserMapper

public interface UserMapper {

    List<User> selectUserList();

    Integer updateUserMoney(Map map);
}

13. 创建mapper映射文件 com.hy.springboot.mapper.UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hy.springboot.mapper.UserMapper">
<select id="selectUserList" resultType="User">
SELECT *
FROM user
</select> <update id="updateUserMoney" parameterType="HashMap">
UPDATE user
SET money = money + #{money}
WHERE id = #{id}
</update>
</mapper>

14. 创建service接口 com.hy.springboot.service.IUserService

public interface IUserService {

    List<User> selectUserList();

    PageWrapper selectUserList(Integer pageNum, Integer pageSize);

    Boolean updateUserMoney(Map map1, Map map2);
}

15. 创建service实现类 com.hy.springboot.service.imp.UserService

@Service
@Transactional
public class UserService implements IUserService { @Autowired
private UserMapper userMapper; @Override
public List<User> selectUserList() {
return userMapper.selectUserList();
} @Override
public PageWrapper selectUserList(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> userList = userMapper.selectUserList();
PageInfo<User> pageInfo = new PageInfo<>(userList);
return new PageWrapper(pageInfo.getTotal(), userList);
} @Override
public Boolean updateUserMoney(Map map1, Map map2) {
Integer integer1 = userMapper.updateUserMoney(map1);
int i = 3 / 0; //模拟异常
Integer integer2 = userMapper.updateUserMoney(map2);
return 0 != integer1 && 0 != integer2;
}
}

16. 创建控制器 com.hy.springboot.controller.TestController

@RestController
@RequestMapping("/test")
public class TestController { @Autowired
private IUserService userService; @RequestMapping("/tm")
public Boolean tm() {
Map<String, Object> map1 = new HashMap<>();
map1.put("id", 6);
map1.put("money", -1000.0);
Map<String, Object> map2 = new HashMap<>();
map2.put("id", 7);
map2.put("money", +1000.0);
return userService.updateUserMoney(map1, map2);
} @RequestMapping("/selectUserList")
public List<User> selectUserList() {
return userService.selectUserList();
} @GetMapping("/selectUserList/{page}/{size}")
public PageWrapper selectUserList(@PathVariable Integer page, @PathVariable Integer size) {
return userService.selectUserList(page, size);
} /** RESTful 只进行演示 没有做数据持久化 **/ @PostMapping("/insert")
public Map insert(String name) {
Map<String, Object> map = new HashMap<>();
map.put("name", name);
return map;
} @PostMapping("/insertX")
public Map insertX(String name, MultipartFile file) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("fileSize", file.getSize()); //建议使用文件服务器保存
return map;
} @DeleteMapping("/delete/{id}")
public Map delete(@PathVariable Integer id, String name) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("name", name);
return map;
} @PutMapping("/update/{id}")
public Map update(@PathVariable Integer id, String name) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("name", name);
return map;
} @PutMapping("/updateX/{id}")
public Map updateX(@PathVariable Integer id, String name, MultipartFile file) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("name", name);
map.put("fileSize", file.getSize()); //建议使用文件服务器保存
return map;
} @GetMapping("/select/{id}")
public Map select(@PathVariable Integer id, String name) {
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("name", name);
return map;
}
}

启动项目 访问 http://localhost:8081/test/selectUserList

android客户端核心代码

public interface Api {

    @POST("/test/insert")
@FormUrlEncoded
Call<ResponseBody> insert(@Field("name") String name); @POST("/test/insertX")
@Multipart
Call<ResponseBody> insertX(@Part MultipartBody.Part name, @Part MultipartBody.Part file); @DELETE("/test/delete/{id}")
Call<ResponseBody> delete(@Path("id") Integer id, @Query("name") String name); @PUT("/test/update/{id}")
@FormUrlEncoded
Call<ResponseBody> update(@Path("id") Integer id, @Field("name") String name); @PUT("/test/updateX/{id}")
@Multipart
Call<ResponseBody> updateX(@Path("id") Integer id, @Part MultipartBody.Part name, @Part MultipartBody.Part file); @GET("/test/select/{id}")
Call<ResponseBody> select(@Path("id") Integer id, @Query("name") String name);
}
private void insert() {
Call<ResponseBody> call = mApi.insert("祎哥哥");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
} private void insertX() {
MultipartBody.Part name = MultipartBody.Part.createFormData("name", "祎哥哥");
RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), card("text.txt"));
MultipartBody.Part file = MultipartBody.Part.createFormData("file", "text.txt", body);
Call<ResponseBody> call = mApi.insertX(name, file);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
} private void delete() {
Call<ResponseBody> call = mApi.delete(3, "黄祎");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
} private void update() {
Call<ResponseBody> call = mApi.update(3, "黄祎");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
} private void updateX() {
MultipartBody.Part name = MultipartBody.Part.createFormData("name", "黄祎");
RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), card("text.txt"));
MultipartBody.Part file = MultipartBody.Part.createFormData("file", "text.txt", body);
Call<ResponseBody> call = mApi.updateX(3, name, file);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
} private void select() {
Call<ResponseBody> call = mApi.select(3, "黄祎");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {} @Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
}

最新文章

  1. 让姑姑不再划拳 码农也要有原则 : SOLID via C#
  2. java 集合
  3. hive 复杂类型
  4. 进一步封装highchart,打造自己的图表插件:jHighChart.js
  5. samba服务器搭建小记
  6. 赴美工作常识(Part 5 - 绿卡优先级)
  7. selenium.Phantomjs设置浏览器请求头
  8. springMVC返回json
  9. Docker网络管理
  10. 文件I/O操作(2)
  11. poj 3630 Phone List(字典树)
  12. PHP 3:从Login界面谈PHP标记
  13. 微信客户端+微信公众平台+新浪云SAE+Arduino+WS100(控制LED)
  14. GitHub使用(二) - 新建文件夹
  15. 《java.util.concurrent 包源码阅读》22 Fork/Join框架的初体验
  16. Java__线程---基础知识全面实战---坦克大战系列为例
  17. c++入门之内置数组和array比较
  18. python中收集函数的解包问题
  19. Java8函数式编程探秘
  20. thinkphp3错误:syntax error, unexpected &#39;list&#39; (T_LIST), expecting identifier (T_STRING)

热门文章

  1. codeforce Round #665(div 2)A B C
  2. 简述BFS与DFS
  3. Windows servers 2008 环境下, DHCP的搭建。
  4. idea创建mybatis的逆向工程:generator
  5. 建设开发者生态:6项华为API管理原则落地
  6. js中使用const声明变量时需要注意
  7. P1082 同余方程(拓展欧几里德)
  8. python3之range()
  9. [bash] 获取linux主机名,检视内中是否有特定字符串
  10. leetcode刷题-59螺旋矩阵2