java微服务开发步骤,开发服务提供者 - 用SpringMVC开发微服务 - 《Apache ServiceComb Java Chassis 用户手册》 - 书栈网 · BookStack...

用SpringMVC 开发微服务

概念阐述

ServiceComb支持SpringMVC注解,允许使用SpringMVC风格开发微服务。建议参照着项目 SpringMVC进行详细阅读

开发示例

步骤 1定义服务接口(可选,方便使用RPC方式调用)

定义接口不是必须的,但是 一个好习惯,可以简化客户端使用RPC方式编写代码。publicinterfaceHello{

StringsayHi(Stringname);

StringsayHello(Personperson);

}

步骤 2实现服务

使用Spring MVC注解开发业务代码,Hello的服务实现如下。在服务的实现类上打上注解@RestSchema,指定schemaId,schemaId必须保证微服务范围内唯一。@RestSchema(schemaId="springmvcHello")

@RequestMapping(path="/springmvchello",produces=MediaType.APPLICATION_JSON)

publicclassSpringmvcHelloImplimplementsHello{

@Override

@RequestMapping(path="/sayhi",method=RequestMethod.POST)

publicStringsayHi(@RequestParam(name="name")Stringname){

return"Hello "+name;

}

@Override

@RequestMapping(path="/sayhello",method=RequestMethod.POST)

publicStringsayHello(@RequestBodyPersonperson){

return"Hello person "+person.getName();

}

}

步骤 3发布服务 (可选,默认会扫描main函数所在的package)

在resources/META-INF/spring目录下创建springmvcprovider.bean.xml文件,命名规则为*.bean.xml,配置spring进行服务扫描的base-package,文件内容如下:<?xml version="1.0"encoding="UTF-8"?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

步骤 4启动provider 服务

下面的代码使用Log4j作为日志记录器。开发者可以方便使用其他日志框架。publicclassSpringmvcProviderMain{

publicstaticvoidmain(String[]args)throwsException{

Log4jUtils.init();

BeanUtils.init();

}

}

Query参数聚合为POJO对象

使用说明

SpringBoot支持将Java业务接口中的多个query参数聚合为一个POJO类,SpringBoot原生用法示例如下:@RequestMapping("/hello")

publicclassHelloService{

@RequestMapping(value="/sayHello",method=RequestMethod.GET)

publicStringsayHello(Personperson){

System.out.println("sayHello is called, person = ["+person+"]");

return"Hello, your name is "+person.getName()+", and age is "+person.getAge();

}

}

其中,作为参数的Person类是一个标准的JavaBean,包含属性name和age。当服务接收到的请求时,SpringBoot会将query参数name和age聚合为Person对象传入业务接口。

ServiceComb的SpringMVC开发模式现在也支持类似的用法,该用法的要求如下:POJO参数上不能有Spring的参数注解,否则ServiceComb不会将其作为聚合的query参数对象处理。

仅支持聚合query参数

POJO参数类中的属性名与query参数名需要保持一致

POJO参数中不支持复杂的属性,如其他POJO对象、List等。用户可以在这些复杂类型打上

consumer端不支持query参数聚合为POJO对象,调用服务时依然要按照契约发送请求。即provider端被聚合的POJO参数在契约中会被展开成一系列的query参数,consumer端需要在provider接口方法中依次定义这些query参数(RPC开发模式),或在发送请求时填入这些query参数(RestTemplate开发模式)。

代码示例

Provider端开发服务Provider端业务接口代码:@RestSchema(schemaId="helloService")

@RequestMapping("/hello")

publicclassHelloService{

@RequestMapping(value="/sayHello",method=RequestMethod.GET)

publicStringsayHello(Personperson){

System.out.println("sayHello is called, person = ["+person+"]");

return"Hello, your name is "+person.getName()+", and age is "+person.getAge();

}

}POJO参数对象定义:publicclassPerson{

privateStringname;

privateintage;

@JsonIgnore// 复杂属性需要标记@JsonIgnore,否则启动时会报错

privateListchildren;

}接口契约:# 忽略契约的其他部分

basePath:"/hello"

paths:

/sayHello:

get:

operationId:"sayHello"

parameters:

# Person类的name属性和age属性作为契约中的query参数

-name:"name"

in:"query"

required:false

type:"string"

-name:"age"

in:"query"

required:false

type:"integer"

format:"int32"

responses:

200:

description:"response of 200"

schema:

type:"string"

Consumer端调用服务consumer端RPC开发模式:Provider接口定义publicinterfaceHelloServiceIntf{

StringsayHello(Stringname,intage);

}调用代码Stringresult=helloService.sayHello("Bob",22);// result的值为"Hello, your name is Bob, and age is 22"consumer端RestTemplate开发模式:Stringresult=restTemplate.getForObject(

"cse://provider-service/hello/sayHello?name=Bob&age=22",

String.class);// 调用效果与RPC方式相同

ServiceComb支持的Spring MVC标签说明

ServiceComb支持使用Spring MVC提供的标签(org.springframework.web.bind.annotation)来声明REST接口,但是两者是独立的实现,而且有不一样的设计目标。CSE的目标是提供跨语言、支持多通信协议的框架,因此去掉了Spring MVC中一些对跨语言支持不是很好的特性,也不支持特定运行框架强相关的特性,比如直接访问Servlet协议定义的HttpServletRequest。ServiceComb没有实现@Controller相关功能, 只实现了@RestController,即通过MVC模式进行页面渲染等功能都是不支持的。

下面是一些具体差异。常用标签支持

下面是CSE对于Spring MVC常用标签的支持情况。

表1-1 Spring MVC注解情况说明标签名称是否支持说明RequestMapping是不允许制定多个Path,一个接口只允许一个Path

GetMapping是

PutMapping是

PostMapping是

DeleteMapping是

PatchMapping是

RequestParam是

CookieValue是

PathVariable是

RequestHeader是

RequestBody是目前支持application/json,plain/text

RequestPart是用于文件上传的场景,对应的标签还有Part、MultipartFile

ResponseBody否返回值缺省都是在body返回

ResponseStatus否可以通过ApiResponse指定返回的错误码

RequestAttribute否Servlet协议相关的标签

SessionAttribute否Servlet协议相关的标签

MatrixVariable否

ModelAttribute否

ControllerAdvice否

CrossOrigin否

ExceptionHandler否

InitBinder否服务声明方式

Spring MVC使用@RestController声明服务,而ServiceComb使用@RestSchema声明服务,并且需要显示的使用@RequestMapping声明服务路径,以区分该服务是采用Spring MVC的标签还是使用JAX RS的标签。@RestSchema(schemaId="hello")

@RequestMapping(path="/")

Schema是CSE的服务契约,是服务运行时的基础,服务治理、编解码等都基于契约进行。在跨语言的场景,契约也定义了不同语言能够同时理解的部分。

最新版本也支持@RestController声明,等价于@RestSchma(schemaId="服务的class名称"),建议用户使用@RestSchema显示声明schemaId,在管理接口基本的配置项的时候,更加直观。数据类型支持

采用Spring MVC,可以在服务定义中使用多种数据类型,只要这种数据类型能够被json序列化和反序列化。比如:// 抽象类型

publicvoidpostData(@RequestBodyObjectdata)

// 接口定义

publicvoidpostData(@RequestBodyIPersoninterfaceData)

// 没指定类型的泛型

publicvoidpostData(@RequestBodyMaprawData)

// 具体协议相关的类型

publicvoidpostData(HttpServletRequestrquest)

ServiceComb会根据接口定义生成契约,从上面的接口定义,如果不结合实际的实现代码或者额外的开发文档说明,无法直接生成契约。也就是站在浏览器的REST视角,不知道如何在body里面构造消息内容。ServiceComb不建议定义接口的时候使用抽象类型、接口等。

为了支持快速开发,ServiceComb的数据类型限制也在不停的扩充,比如支持HttpServletRequest,Object等。但是实际在使用的时候,他们与WEB服务器的语义是不一样的,比如不能直接操作流。因此建议开发者在ServiceComb的使用场景下,尽可能使用契约能够描述的类型,让代码阅读性更好。

ServiceComb在数据类型的支持方面的更多说明,请参考: 接口定义和数据类型其他更多开发过程中碰到的问题,可以参考案例。开发过程中存在疑问,也可以在这里进行提问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值