微服务SpringCloud 第一节 Spring Boot
研究微服务器框架SpringCloud,记录成果,以备后用。
Spring Cloud离不开SpringBoot 。Spring Cloud框架中的各个微服务都是由Spring Boot项目组成。
Spring Boot的出现,大大简化了Spring应用从创建到发布部署的整个过程:创建应用工程很简单;pom管理的jar包依赖井然有序;本身提供或者第三方提供的starter包很好用;大部分的配置都做了最符合习惯的默认设置,可以很少配置,甚至零配置(当然实际开发中开始需要做一些配置的);内嵌web容器(tomcat,jetty),部署发布只需要一个jar包等等。
Spring Boot就是由一个个starter组成。每个starter都包含至少一个完整的功能以及必要的jar依赖,starter帮助我们简化了pom依赖。
创建一个SpringBoot工程是非常简单的。以IDEA为例
- 创建一个project
- 选择Maven,SDK要选择1.8版本的JDK,因为SpringBoot不支持1.8以下的JDK版本。
- 设置GroupId和ArtifactId,最好用公司名称,这里只是举个栗子
- 选定工程目录
- 刚进来时是这样子的
- 修改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.example</groupId> <artifactId>miniservice</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>miniservice</name> <description>Demo project for miniservice</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.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> <com.alibaba.fastjson.version>1.2.47</com.alibaba.fastjson.version> </properties> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> </dependencies> </project>
spring-boot-starter-parent必不可少,它规定了Spring Boot的版本,以及依赖的统一管理。
lombok是一个java插件,我用来简写代码和统一风格,非常好用。
-
父pom创建好了,接下来,新建一个module:miniservice-demo。项目上点右键
-
生成miniservice-demo后,创建必要的java类,静态文件目录,html文件目录,配置文件application.properties。并修改module的pom.xml添加必要的依赖和打包插件。
package com.example.demo.configure;
import com.example.demo.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@ControllerAdvice
@Slf4j
public class GloabExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public ModelAndView handleNotFoundException(HttpServletRequest request,
NoHandlerFoundException ex) {
handleLog(request, ex);
ModelAndView view = new ModelAndView("error/404");
view.addObject(Result.error( HttpStatus.NOT_FOUND.value(),ex==null?"":ex.getMessage()));
return view;
}
@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ModelAndView handleAllException(HttpServletRequest request,
Exception ex) {
ModelAndView view = new ModelAndView("error/500");
view.addObject(Result.error( HttpStatus.INTERNAL_SERVER_ERROR.value(),ex==null?"":ex.getMessage()));
return view;
}
private void handleLog(HttpServletRequest request, Exception ex) {
Map parameter = request.getParameterMap();
StringBuffer logBuffer = new StringBuffer();
if (request != null) {
logBuffer.append(" request method=" + request.getMethod());
logBuffer.append(" url=" + request.getRequestURL());
}
if (ex != null) {
logBuffer.append(" exception:" + ex);
}
log.error(logBuffer.toString());
}
}
<?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">
<parent>
<artifactId>miniservice</artifactId>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>miniservice-demo</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<finalName>miniserviceDemo</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.demo.DemoApplication</mainClass>
<executable>true</executable>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.example.demo.util;
import java.io.Serializable;
/**
* 统一API响应结果封装
*/
public class Result<T> implements Serializable {
private int code;
private String message;
private T data;
public static final int SUCCESS = 200;
public static final int FAIL = 400;
public static final int NOT_FOUND = 404;
public static final int ERROR = 500;
public static final int NO_LOGIN = 300;
public Result() {
}
public Result(int code, String msg, T data) {
this.setCode(code);
this.setMessage(msg);
this.setData(data);
}
public void setCode(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public Result setMessage(String message) {
this.message = message;
return this;
}
public T getData() {
return data;
}
public Result setData(T data) {
this.data = data;
return this;
}
public static <T> Result<T> success() {
return new Result<T>(SUCCESS, "success", null);
}
public static <T> Result<T> success(String message) {
return new Result<T>(SUCCESS, message, null);
}
public static <T> Result<T> success(T data) {
return new Result<T>(SUCCESS, "success", data);
}
public static <T> Result<T> success(String message, T data) {
return new Result<T>(SUCCESS, message, data);
}
public static <T> Result<T> error() {
return new Result<T>(ERROR, "fail", null);
}
public static <T> Result<T> clientfail() {
return new Result<T>(ERROR, "clientfail", null);
}
public static <T> Result<T> error(int code,String errorMsg,T data) {
return new Result<T>(code, errorMsg, data);
}
public static <T> Result<T> error(int code,String errorMsg) {
return error(code,errorMsg,null);
}
public static <T> Result<T> error(String message) {
return new Result<T>(ERROR, message, null);
}
public static <T> Result<T> error(T data) {
return new Result<T>(ERROR, "fail", data);
}
public static <T> Result<T> error(String message, T data) {
return new Result<T>(ERROR, message, data);
}
public static <T> Result<T> badrequest() {
return new Result<T>(FAIL, "no identifier arguments", null);
}
public static <T> Result<T> badrequest(String message) {
return new Result<T>(FAIL, message, null);
}
public static <T> Result<T> badrequest(T data) {
return new Result<T>(FAIL, "no identifier arguments", data);
}
public static <T> Result<T> badrequest(String message, T data) {
return new Result<T>(FAIL, message, data);
}
public static <T> Result<T> noLogin(String message) {
return new Result<T>(NO_LOGIN, message, null);
}
public static <T> Result<T> notFound() {
return new Result<T>(NOT_FOUND, "handler not found", null);
}
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author : david.ye<br>
* @version : v1.0
* @Description :
* @since : 2018/7/26 15:02<br>
*/
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args){
SpringApplication.run(DemoApplication.class,args);
}
}
package com.example.demo.controller;
import org.apache.catalina.util.RequestUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
/**
* @author : david.ye<br>
* @version : v1.0
* @Description :
* @since : 2018/7/26 15:14<br>
*/
@Controller
@RequestMapping("/demo")
public class DemoController {
@GetMapping("/{code}")
public String validErrorPage(@PathVariable(name = "code")int code, HttpServletRequest request) throws Exception {
if(code==200){
request.setAttribute("message",code+"这是demo页面!!!!!");
return "demo";
}else if(code==404){
throw new NoHandlerFoundException(request.getMethod(),request.getRequestURI(),null);
}else{
throw new Exception();
}
}
}
application.properties
#异常信息自定义
spring.mvc.throw-exception-if-no-handler-found=true
#编码
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8
#port
server.port=8080
执行main方法,启动工程访问http://localhost:8080/demo/200,页面如下所示
试试访问一个随意的链接http://localhost:8080/demo:
备注:自定义的错误页404一定要放到templates/error下面 否则@ControllerAdvice会拦截不到404错误
附件下载:miniservice.rar
推荐阅读
-
SpringCloud之服务注册与发现Spring Cloud Eureka实例代码
-
Spring Boot Dubbo 构建分布式服务的方法
-
实战SpringCloud响应式微服务系列教程(第九章)使用Spring WebFlux构建响应式RESTful服务
-
Spring框架学习笔记(6)——阿里云服务器部署Spring Boot项目(jar包)
-
Spring boot项目部署到云服务器小白教程详解
-
Spring boot Mybatis整合构建Rest服务(超细版)
-
微服务架构盛行的时代,你需要了解点 Spring Boot
-
荐 微服务之Spring Boot2—降低开发复杂度之面向切面AOP
-
spring Boot+spring Cloud实现微服务详细教程第二篇
-
spring boot 集成 zookeeper 搭建微服务架构