身为一个Android开发,相信在大家的工作当中,和后台互相撕逼,一定是常有的事,经常我们需要这样的字段和格式,后台却给我另外的,很蛋疼。当然,如果前期接口文档定义好了的话,这样的问题一般很少出现,但是遗憾的是,大多数情况下,文档是不完善的,互相扯皮是常有的事。于是,我就萌发了自己去写后台接口的想法,本文就是我学习SpringBoot的笔记。
其实能写接口的框架太多了,比如php的ThinkPHP、python的Django和Flask,还有Java的SpringMVC,那么,为什么选择了SpringBoot呢?
其实很简单,首先我觉得Java是世界上最好的语言(恩,我就是要挑起战争),做Android做久了,对Java感觉特别亲切,从Android出发去学习后台开发的话,SpringBoot是不二之选。同时,SpringBoot是约定大于配置的典范,它本身集成了SpringMVC、Jackson, JDBC, Mongo, Redis, Mail等大量的组件,极简配置,开箱即用,对新手非常友好。
更重要的是:学习SpringBoot是为之后学习SpringCloud打基础,这年头,不玩点微服务怎么好意思是做后台开发。而SpringCloud已经为我们提供了在分布式系统的配置管理、服务发现、断路器、智能路由、微代理、控制总线等开发工具包,怎么能不去好好的玩一玩呢?
1.SpringBoot项目配置
创建项目:Spring Initializer
选择创建Spring Initializer项目
勾选web组件
创建完成后的项目结构如图所示
依赖管理: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.imooc</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>user</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
环境参数:application.yml
当然你也可以用properties来配置,但我更喜欢yml,因为它的层次结构更简单明了
spring:
profiles:
active: dev
jpa:
hibernate:
ddl-auto: update
show-sql: true
---
#开发环境配置
spring:
profiles: dev
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/devdb
username: root
password: 123456
server:
port: 8080
context-path: /demodev
---
#测试环境配置
spring:
profiles: test
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/testdb
username: root
password: 123456
server:
port: 8081
context-path: /demotest
---
#生产环境配置
spring:
profiles: pro
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/prodb
username: root
password: 123456
server:
port: 8082
context-path: /demopro
2.简单的返回值
返回字符串数据
package com.example.easy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* yutianran 2017/1/19 下午6:33
*/
@RestController
public class HelloController {
@RequestMapping(value = "hello")
public String say(){
return "Hello Spring Boot!";
}
}
请求结果如下:
返回json数据
package com.example.easy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* yutianran 2017/1/19 下午6:35
*/
@RestController
public class JsonController {
@RequestMapping("json")
public Person resp(){
Person xiaoming = new Person("xiaoming", 23);
return xiaoming;
}
}
请求结果如下:
3.数据库操作
实体类:@Entity
有了这个注解,你就不用再自己去写SQL创建表了,SpringBoot会自动扫描带有这个注解的类,然后通过对象关系映射,自动帮我们创建表。
关于对象关系映射:请查看我的博文自定义ORM框架
package com.example.db;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* yutianran 2017/1/19 下午8:39
*/
@Entity
public class User {
@Id
@GeneratedValue
private Integer id;
private String name;
private Integer age;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
持久层:@Repository
package com.example.db;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 持久层
* <p/>
* yutianran 2017/1/19 下午9:04
*/
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
//通过年龄来查询
List<User> findByAge(Integer age);
}
控制层:@RestController
这里我直接用的@RestController注解
它等价于@Controller+@ResponseBody
package com.example.db;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 控制层
* <p/>
* yutianran 2017/1/19 下午9:02
*/
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private UserService userService;
/**
* 通用的增删改查(JpaRepository自带)
*
* @return
*/
@GetMapping("findAll")
public List<User> getAll() {
return userRepository.findAll();
}
@PostMapping("save")
public User save(@RequestParam("name") String name, @RequestParam("age") Integer age) {
System.out.println("name=" + name + "\tage=" + age);
User user = new User();
user.setName(name);
user.setAge(age);
return userRepository.save(user);
}
@PostMapping("findOne")
public User findOne(@RequestParam("id") Integer id) {
System.out.println("id=" + id);
return userRepository.findOne(id);
}
@PostMapping("update")
public User update(@RequestParam("id") Integer id, @RequestParam("name") String score, @RequestParam("age") Integer age) {
System.out.println("name=" + score + "\tage=" + age);
User user = new User();
user.setId(id);//带有id,表示更新
user.setName(score);
user.setAge(age);
return userRepository.save(user);
}
@PostMapping("delete")
public void delete(@RequestParam("id") Integer id) {
System.out.println("id=" + id);
userRepository.delete(id);
}
/**
* 自定义的操作
*
* @param age
* @return
*/
@PostMapping("findByAge")
public List<User> findByAge(@RequestParam("age") Integer age) {
return userRepository.findByAge(age);
}
@PostMapping("addTwo")
public void addTwo(@RequestParam("a") String a, @RequestParam("b") String b) {
userService.insertTwo(a, b);
}
}
服务层:@Service
在控制层,我们依赖了一个服务。
package com.example.db;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 服务层
* <p/>
* yutianran 2017/1/19 下午10:02
*/
@Service
public class UserService {
@Autowired
private UserRepository repository;
@Transactional
public void insertTwo(String a, String b) {
User userA = new User();
userA.setName(a);
userA.setAge(21);
repository.save(userA);
User userB = new User();
userB.setName(b);
userB.setAge(22);
repository.save(userB);
}
}
测试添加数据
使用DHC发送请求
查看数据库
4.文件上传和下载
文件上传和下载的控制层
package com.example.file;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
/**
* yutianran 2017/1/19 下午10:29
*/
@Controller
@RequestMapping("file")
public class FileController {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
@RequestMapping("file")
public String file() {
return "file";//返回网页模板
}
@RequestMapping("upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
if (!file.isEmpty()) {
String time = sdf.format(System.currentTimeMillis());
File dest = new File("/Users/yutianran/Desktop", time + "_" + file.getOriginalFilename());
FileUtils.copyInputStreamToFile(file.getInputStream(), dest);
}
return "上传成功";
}
@RequestMapping("download")
public ResponseEntity<byte[]> download() throws IOException {
String filename = "down.jpg";
File file = new File("/Users/yutianran/Pictures", filename);
//封装http头部信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", filename);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
}
文件上传的网页模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="upload">
<p>文件:<input type="file" name="file"/></p>
<p><input type="submit" value="上传"/></p>
</form>
</body>
</html>
测试图片上传
用浏览器访问:http://127.0.0.1:8080/demodev/file/file
选择图片后
上传图片后
测试图片下载
最后,按照老规矩,奉上源码:Github-SpringBootDemo
帮朋友打个广告,友情链接:有心课堂,传递给你的不仅仅是技术
网友评论