安卓开发Demo

写接口不求人,SpringBoot入门

2017-04-06  本文已影响4780人  小鱼爱记录

身为一个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

帮朋友打个广告,友情链接:有心课堂,传递给你的不仅仅是技术

上一篇下一篇

猜你喜欢

热点阅读