发布:2021/7/31 17:46:05作者:管理员 来源:本站 浏览次数:1366
Dubbo 框架现在在国内的中小企业当中已经成为 Java 生态下服务化的事实标准,出现这种状态的原因很多,比如 Dubbo 框架设计优秀、文档和资料丰富、配置灵活、特性丰富等,但最主要的,我认为是 Java 开发人员对速度这一因素的痴迷。{ "code" : 1, "error" : "XXXXX", "data" : { ... }}
其中,code 表示调用结果的状态,0 表示成功,非 0 表示失败,并且失败情况下 error 字段将提供对应的错误信息描述,data 字段用于规范定义特定于 Web API 的响应内容。
- <?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.keevol.springboot.chapter4</groupId>
- <artifactId>currency-webapi</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>currency-webapi</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.3.1.RELEASE</version>
- <relativePath /> <!-- lookup parent from repository -->
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>com.keevol.springboot</groupId>
- <artifactId>currency-rates-service</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
- @Controller
- public class CurrencyRateQueryController {
- @Autowired
- private CurrencyRateService currencyRateService;
- @RequestMapping(value = "/", method = RequestMethod.GET)
- @ResponseBody
- public ExchangeRate quote(String symbol) throws IOException {
- return currencyRateService.quote(CurrencyPair.from(symbol));
- }
- }
{ currencyPair: { symbol: “USD/CNY” }, bidPrice: 6.67, askPrice: 6.56}
整个 Web API 的功能流程算是跑通了,但跟我们之前定义的 Web API 规范却没有关系,所以,下一步我们要做的事情就是在此基础上规范 HTTP 响应格式,使其遵循我们之前定义的 Web API 规范,从而任何访问我们提供的 Web API 访问者都可以相同的认知使用这些 Web API,进而也可以打造和沉淀相应的工具或者类库。
- public class WebApiResponse<T> {
- public static final int SUCCESS_CODE = 0;
- public static final int ERROR_CODE = 1;
- private int code;
- private String error;
- private T data;
- // getters, setters, toString(), etc.
- }
- @RequestMapping(value = "/", method = RequestMethod.GET)
- @ResponseBody
- public WebApiResponse<ExchangeRate> quote(String symbol) throws IOException {
- WebApiResponse<ExchangeRate> response = new WebApiResponse<>();
- response.setCode(WebApiResponse.SUCCESS_CODE);
- response.setData(currencyRateService.quote(CurrencyPair.from(symbol)));
- return response;
- }
- public class WebApiResponse<T> {
- public static final int SUCCESS_CODE = 0;
- public static final int ERROR_CODE = 1;
- private int code;
- private String error;
- private T data;
- public static <T> WebApiResponse<T> success(T data) {
- WebApiResponse<T> response = new WebApiResponse<>();
- response.setCode(SUCCESS_CODE);
- response.setData(data);
- return response;
- }
- public static <T> WebApiResponse<T> error(String errorMessage) {
- return WebApiResponse.<T>error(errorMessage, ERROR_CODE);
- }
- // ...
- @RequestMapping(value = "/", method = RequestMethod.GET)
- @ResponseBody
- public WebApiResponse<ExchangeRate> quote(String symbol) throws IOException {
- return WebApiResponse.success(currencyRateService.quote(CurrencyPair.from(symbol)));
- }
- }
- @RequestMapping(value = "/", method = RequestMethod.GET)
- @ResponseBody
- public ExchangeRate quote(String symbol) throws IOException {
- return currencyRateService.quote(CurrencyPair.from(symbol));
- }
- public class JsonHttpMessageConverter extends AbstractHttpMessage-Converter<Object> {
- @Override
- protected boolean supports(Class<?> clazz) {
- return !clazz.isPrimitive();
- }
- @Override
- protected Object readInternal(Class<?> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
- return null;
- }
- @Override
- protected void writeInternal(Object o, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
- httpOutputMessage.getHeaders().add("Content-Type", "application/json");
- // 其他header设置
- // toJson()方法中可以使用jackson或者fastjson等类库完成对象到json的转换
- httpOutputMessage.getBody().write(toJson(o));
- httpOutputMessage.getBody().flush();
- }
- }
- @Configuration
- public class WebApiConfiguration extends WebMvcConfigurerAdapter {
- @Override
- public void extendMessageConverters(List<HttpMessageConvert-er<?>> converters) {
- // 添加或者插入我们自定义的HttpMessageConverter实现类
- // converters.add(converter)或者converters.add(0, converter)
- }
- }
- for(HttpMessageConverter converter: converters){
- if(converter.canWrite(clazz, media)) {
- converter.write(..);
- }
- }
- <?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>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starters</artifactId>
- <version>1.2.5.RELEASE</version>
- </parent>
- <groupId>com.keevol.springboot</groupId>
- <artifactId>spring-boot-starter-webapi</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>spring-boot-starter-webapi</name>
- <url></url>
- <properties>
- <java.version>1.8</java.version>
- <file.encoding>UTF-8</file.encoding>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.2</version>
- <configuration>
- <source>${java.version}</source>
- <target>${java.version}</target>
- <encoding>${file.encoding}</encoding>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger2</artifactId>
- <version>2.1.2</version>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger-ui</artifactId>
- <version>2.1.2</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>javax.servlet-api</artifactId>
- <version>${servlet-api.version}</version>
- </dependency>
- </dependencies>
- </project>
- @Configuration
- @EnableSwagger2
- @ComponentScan("com.wacai.springboot.webapi.errors")
- @AutoConfigureAfter(WebMvcAutoConfiguration.class)
- public class WebApiAutoConfiguration extends WebMvcConfigurerAdapter {
- protected Logger logger = LoggerFactory.getLogger(WebApiAuto - Configuration.class);
- @Value("${springfox.api.group:[your api group name]}")
- private String apiGroupName;
- @Value("${springfox.api.title:[set a api title via 'springfox.api.title']}")
- private String title;
- @Value("${springfox.api.description:[add your api description via 'springfox.api.description'}]")
- private String desc;
- @Value("${springfox.api.version:[set specific api version via 'springfox.api.version'}]")
- private String version;
- @Value("${springfox.api.termsOfServiceUrl:[set termsOf-ServiceUrl via 'springfox.api.termsOfServiceUrl']}")
- private String termsOfServiceUrl;
- @Value("${springfox.api.contact:[set contact via 'springfox.api.contact'}]")
- private String contact;
- @Value("${springfox.api.license:Your WebAPI License}")
- private String license;
- @Value("${springfox.api.licenseUrl:http://keevol.com}")
- private String licenseUrl;
- @Autowired
- private TypeResolver typeResolver;
- @Bean
- public Docket api() {
- return new Docket(DocumentationType.SWAGGER_2).groupName(apiGroupName)
- .apiInfo(new ApiInfo(title, desc, version, termsOf - ServiceUrl, contact, license, licenseUrl)).select()
- .apis(RequestHandlerSelectors.any()).paths(excludedPathSelector()).build().pathMapping("/")
- .directModelSubstitute(Date.class, String.class).genericModelSubstitutes(ResponseEntity.class)
- .alternateTypeRules(newRule(
- typeResolver.resolve(DeferredResult.class,
- typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
- typeResolver.resolve(WildcardType.class)))
- .useDefaultResponseMessages(false)
- .globalResponseMessage(RequestMethod.GET, newArrayList(new ResponseMessageBuilder().code(500)
- .message("服务出错啦~").responseModel(new ModelRef("Error")).build()))
- .forCodeGeneration(true);
- }
- // ...
- }
- <dependency>
- <groupId>com.keevol.springboot</groupId>
- <artifactId>spring-boot-starter-webapi</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4