介绍

本文介绍基于SpringBoot搭建一个简单的Web服务。主要包含以下几个部分:

  • build.gradle文件加载依赖和设置打包方法
  • settings.gradle文件加载module
  • 新建Application类,启动main方法
  • 新建Controller类,定义Handler和处理内部逻辑
  • 新建Request和Response类,完成请求参数和返回参数的构造
  • 新建properties文件,设置服务相关参数

下面详细介绍。

主要构成

build.gradle

新建build.gradle文件加载SpringBoot依赖和搭建Web服务的依赖,项目名称为hello,代码如下:

// springboot设置
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath('org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE')
        classpath('org.springframework.boot:spring-boot-loader-tools:1.4.0.RELEASE')
        classpath('org.springframework:spring-core:4.3.2.RELEASE')
        classpath("io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE")
    }
}

//整个项目设置
allprojects {
    group 'hello'
    version '1.0-SNAPSHOT'
    apply plugin: 'java'
}

subprojects {
    // 打war包
    apply plugin : 'war'

    // 使用spring-boot插件
    apply plugin : 'spring-boot'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    repositories {
        mavenCentral()
    }

    dependencies {
        compile("org.springframework.boot:spring-boot-starter-actuator:1.4.0.RELEASE")
        compile("org.springframework.boot:spring-boot-starter-web:1.4.0.RELEASE")
        compile("com.fasterxml.jackson.core:jackson-databind:2.8.1")
    }
}

//module设置
project(':web') {
    war {
        baseName = 'web'
    }

    // 主函数对应的class设置
    bootRepackage {
        mainClass = "hello.HelloApplication"
    }
}

settings.gradle

settings.gradle文件用来加载对应的module,代码如下:

rootProject.name = 'hello'
include 'web'

Application类

添加module名称记为web,新建package名称记为hello,在该package下新建Application,名称为HelloApplication,添加@SpringBootApplication定义为SpringBoot。代码如下:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by eyangmeng@163.com on 2018/8/9.
 */

@SpringBootApplication(scanBasePackages = "hello")
public class HelloApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

Controller类

在package=hello下新建package名称记为controller,即package=package hello.controller,新建HelloController,添加@RestController注解,新建handler,完成内部逻辑处理。代码如下:

package hello.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import hello.domain.HelloRequest;
import hello.domain.HelloResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;


/**
 * Created by eyangmeng@163.com on 2018/8/9.
 */

@RestController
public class HelloController {

    /**
     * 接收name和age, 返回一个string
     * 
     * @param request 请求参数处理
     * @param errors  错误
     * @return a string
     */
    @RequestMapping("/server")
    String process(@Valid HelloRequest request, Errors errors) {
        try {
            String res = String.format("User info: Name: %s, Age: %s.", request.getName(), request.getAge());
            HelloResponse response = new HelloResponse(0, "ok", res);
            return new ObjectMapper().writeValueAsString(response);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            return null;
        }
    }

    private static final Logger LOG = LoggerFactory.getLogger(HelloController.class);
}

Request和Response类

在package=hello下新建package名称记为domain,即package=hello.controller,新建Request和Response类,完成请求参数和返回参数的构造。代码如下:

  • HelloRequest 处理请求参数
package hello.domain;

/**
* Created by eyangmeng@163.com on 2018/8/9.
*/
public class HelloRequest {

  private String name;
  private String age;

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public String getAge() {
      return age;
  }

  public void setAge(String age) {
      this.age = age;
  }
}
  • HelloResponse 作为结果返回
package hello.domain;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Created by eyangmeng@163.com on 2018/8/9.
*/
public class HelloResponse {

  public HelloResponse() {}

  public HelloResponse(int status, String message, String response) {
      this.status = status;
      this.message = message;
      this.response = response;
  }

  @JsonProperty("response")
  private String response;

  @JsonProperty("status_code")
  private int status;

  @JsonProperty("status_message")
  private String message;

  public String getResponse() {
      return response;
  }

  public void setResponse(String response) {
      this.response = response;
  }

  public int getStatus() {
      return status;
  }

  public void setStatus(int status) {
      this.status = status;
  }

  public String getMessage() {
      return message;
  }

  public void setMessage(String message) {
      this.message = message;
  }
}

properties文件

在src/resources/下新建application.properties文件设置服务相关参数,如服务端口等,代码如下:

# debug模式
debug=false
spring.main.banner_mode=off
spring.output.ansi.enable=ALWAYS

# 服务端口
server.port=8080

服务验证

启动服务

依据上述的说明,我们基本可以把简单的Web服务搭建完成,启动服务。以下输入显示服务正常启动。

2018-08-09 22:31:25.481  INFO 5260 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-08-09 22:31:25.714  INFO 5260 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-08-09 22:31:25.773  INFO 5260 --- [           main] hello.HelloApplication                   : Started HelloApplication in 8.777 seconds (JVM running for 9.999)

服务验证

我们在本机搭建web服务,端口设置为8080,介绍name和age两个字符串参数。请求示例如下:

http://localhost:8080/server?name=hello&age=20

返回结果如下:

{
    "response":"User info: Name: hello, Age: 20.",
    "status_code":0,
    "status_message":"ok"
}

总结

我们利用SpringBoot搭建简单的Web服务,对整个流程有了大致的了解。有以下几个问题需要后续解决:

  1. 输入参数如何统一添加参数验证机制? @InitBinder注解
  2. 为Controller中的Handler添加统一的切面,添加日志记录输入参数,输出参数,异常处理? @Aspect注解
  3. 封装Response构造相对统一的构造返回值的方法? 构造泛型函数
  4. 等等

参考文献

https://spring.io/guides/gs/spring-boot/