1:认识Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。

作用:

    1. 接口的文档在线自动生成。

    2. 功能测试。

 Swagger是一组开源项目,其中主要要项目如下:

1.   Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger 2.0文档等功能。

2.   Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。

3.   Swagger-js: 用于JavaScript的Swagger实现。

4.   Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。

5.   Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。

6.   Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。

2:Maven

版本号请根据实际情况自行更改。

<dependency>

<groupId>io.springfox</groupId>

<artifactId>springfox-swagger2</artifactId>

<version>2.2.2</version>

</dependency>

<dependency>

<groupId>io.springfox</groupId>

<artifactId>springfox-swagger-ui</artifactId>

<version>2.2.2</version>

</dependency>

3:创建Swagger2配置类

在Application.java同级创建Swagger2的配置类Swagger2

  1.  
    package com.swaggerTest;
  2.  
     
  3.  
    import org.springframework.context.annotation.Bean;
  4.  
    import org.springframework.context.annotation.Configuration;
  5.  
     
  6.  
    import springfox.documentation.builders.ApiInfoBuilder;
  7.  
    import springfox.documentation.builders.PathSelectors;
  8.  
    import springfox.documentation.builders.RequestHandlerSelectors;
  9.  
    import springfox.documentation.service.ApiInfo;
  10.  
    import springfox.documentation.spi.DocumentationType;
  11.  
    import springfox.documentation.spring.web.plugins.Docket;
  12.  
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
  13.  
     
  14.  
    /**
  15.  
    * Swagger2配置类
  16.  
    * 在与spring boot集成时,放在与Application.java同级的目录下。
  17.  
    * 通过@Configuration注解,让Spring来加载该类配置。
  18.  
    * 再通过@EnableSwagger2注解来启用Swagger2。
  19.  
    */
  20.  
    @Configuration
  21.  
    @EnableSwagger2
  22.  
    public class Swagger2 {
  23.  
     
  24.  
    /**
  25.  
    * 创建API应用
  26.  
    * apiInfo() 增加API相关信息
  27.  
    * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
  28.  
    * 本例采用指定扫描的包路径来定义指定要建立API的目录。
  29.  
    *
  30.  
    * @return
  31.  
    */
  32.  
    @Bean
  33.  
    public Docket createRestApi() {
  34.  
    return new Docket(DocumentationType.SWAGGER_2)
  35.  
    .apiInfo(apiInfo())
  36.  
    .select()
  37.  
    .apis(RequestHandlerSelectors.basePackage("com.swaggerTest.controller"))
  38.  
    .paths(PathSelectors.any())
  39.  
    .build();
  40.  
    }
  41.  
     
  42.  
    /**
  43.  
    * 创建该API的基本信息(这些基本信息会展现在文档页面中)
  44.  
    * 访问地址:http://项目实际地址/swagger-ui.html
  45.  
    * @return
  46.  
    */
  47.  
    private ApiInfo apiInfo() {
  48.  
    return new ApiInfoBuilder()
  49.  
    .title("Spring Boot中使用Swagger2构建RESTful APIs")
  50.  
    .description("更多请关注http://www.baidu.com")
  51.  
    .termsOfServiceUrl("http://www.baidu.com")
  52.  
    .contact("sunf")
  53.  
    .version("1.0")
  54.  
    .build();
  55.  
    }
  56.  
    }

如上代码所示,通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。

4:添加文档内容

在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,描述的主要来源是函数的命名,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容。

Swagger使用的注解及其说明:

@Api:用在类上,说明该类的作用。

@ApiOperation:注解来给API增加方法说明。

@ApiImplicitParams : 用在方法上包含一组参数说明。

@ApiImplicitParam:用来注解来给方法入参增加说明。

@ApiResponses:用于表示一组响应

@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息

l   code:数字,例如400

l   message:信息,例如"请求参数没填好"

l   response:抛出异常的类

@ApiModel:描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)

l   @ApiModelProperty:描述一个model的属性

注意:@ApiImplicitParam的参数说明:

paramType:指定参数放在哪个地方

header:请求参数放置于Request Header,使用@RequestHeader获取

query:请求参数放置于请求地址,使用@RequestParam获取

path:(用于restful接口)-->请求参数的获取:@PathVariable

body:(不常用)

form(不常用)

name:参数名

dataType:参数类型

required:参数是否必须传

true | false

value:说明参数的意思

defaultValue:参数的默认值

例子:

  1.  
    package com.swaggerTest.controller;
  2.  
     
  3.  
    import org.springframework.stereotype.Controller;
  4.  
    import org.springframework.util.StringUtils;
  5.  
    import org.springframework.web.bind.annotation.RequestMapping;
  6.  
    import org.springframework.web.bind.annotation.RequestMethod;
  7.  
    import org.springframework.web.bind.annotation.RequestParam;
  8.  
    import org.springframework.web.bind.annotation.ResponseBody;
  9.  
     
  10.  
    import io.swagger.annotations.Api;
  11.  
    import io.swagger.annotations.ApiImplicitParam;
  12.  
    import io.swagger.annotations.ApiImplicitParams;
  13.  
    import io.swagger.annotations.ApiOperation;
  14.  
     
  15.  
    /**
  16.  
    * 一个用来测试swagger注解的控制器
  17.  
    * 注意@ApiImplicitParam的使用会影响程序运行,如果使用不当可能造成控制器收不到消息
  18.  
    *
  19.  
    * @author SUNF
  20.  
    */
  21.  
    @Controller
  22.  
    @RequestMapping("/say")
  23.  
    @Api(value = "SayController|一个用来测试swagger注解的控制器")
  24.  
    public class SayController {
  25.  
     
  26.  
    @ResponseBody
  27.  
    @RequestMapping(value ="/getUserName", method= RequestMethod.GET)
  28.  
    @ApiOperation(value="根据用户编号获取用户姓名", notes="test: 仅1和2有正确返回")
  29.  
    @ApiImplicitParam(paramType="query", name = "userNumber", value = "用户编号", required = true, dataType = "Integer")
  30.  
    public String getUserName(@RequestParam Integer userNumber){
  31.  
    if(userNumber == 1){
  32.  
    return "张三丰";
  33.  
    }
  34.  
    else if(userNumber == 2){
  35.  
    return "慕容复";
  36.  
    }
  37.  
    else{
  38.  
    return "未知";
  39.  
    }
  40.  
    }
  41.  
     
  42.  
    @ResponseBody
  43.  
    @RequestMapping("/updatePassword")
  44.  
    @ApiOperation(value="修改用户密码", notes="根据用户id修改密码")
  45.  
    @ApiImplicitParams({
  46.  
    @ApiImplicitParam(paramType="query", name = "userId", value = "用户ID", required = true, dataType = "Integer"),
  47.  
    @ApiImplicitParam(paramType="query", name = "password", value = "旧密码", required = true, dataType = "String"),
  48.  
    @ApiImplicitParam(paramType="query", name = "newPassword", value = "新密码", required = true, dataType = "String")
  49.  
    })
  50.  
    public String updatePassword(@RequestParam(value="userId") Integer userId, @RequestParam(value="password") String password,
  51.  
    @RequestParam(value="newPassword") String newPassword){
  52.  
    if(userId <= 0 || userId > 2){
  53.  
    return "未知的用户";
  54.  
    }
  55.  
    if(StringUtils.isEmpty(password) || StringUtils.isEmpty(newPassword)){
  56.  
    return "密码不能为空";
  57.  
    }
  58.  
    if(password.equals(newPassword)){
  59.  
    return "新旧密码不能相同";
  60.  
    }
  61.  
    return "密码修改成功!";
  62.  
    }
  63.  
    }

完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html

如上图,可以看到暴漏出来的控制器信息,点击进入可以看到详细信息。

两个注意点:

1.  paramType会直接影响程序的运行期,如果paramType与方法参数获取使用的注解不一致,会直接影响到参数的接收。

例如:

使用Sawgger UI进行测试,接收不到!

2.  还有一个需要注意的地方:

Conntroller中定义的方法必须在@RequestMapper中显示的指定RequestMethod类型,否则SawggerUi会默认为全类型皆可访问, API列表中会生成多条项目。

如上图:updatePassword()未指定requestMethod,结果生成了7条API信息。所以如果没有特殊需求,建议根据实际情况加上requestMethod。

5:Swagger UI面板说明

6:参考

http://blog.didispace.com/springbootswagger2/

http://blog.csdn.net/jia20003/article/details/50700736

Swagger官网 :http://swagger.io/

Spring Boot & Swagger UI : http://fruzenshtein.com/spring-boot-swagger-ui/

Github:https://github.com/swagger-api/swagger-core/wiki/Annotations

---------------------------------------------------------------------------------------

7:接收对象传参的例子

在POJO上增加

  1.  
     
  2.  
    package com.zhongying.api.model.base;
  3.  
     
  4.  
    import io.swagger.annotations.ApiModel;
  5.  
    import io.swagger.annotations.ApiModelProperty;
  6.  
     
  7.  
    /**
  8.  
    * 医生对象模型,不要使用该类
  9.  
    * @author SUNF
  10.  
    *
  11.  
    */
  12.  
    @ApiModel(value="医生对象模型")
  13.  
    public class DemoDoctor{
  14.  
    @ApiModelProperty(value="id" ,required=true)
  15.  
    private Integer id;
  16.  
    @ApiModelProperty(value="医生姓名" ,required=true)
  17.  
    private String name;
  18.  
     
  19.  
     
  20.  
    public Integer getId() {
  21.  
    return id;
  22.  
    }
  23.  
     
  24.  
    public void setId(Integer id) {
  25.  
    this.id = id;
  26.  
    }
  27.  
     
  28.  
    public String getName() {
  29.  
    return name;
  30.  
    }
  31.  
     
  32.  
    public void setName(String name) {
  33.  
    this.name = name;
  34.  
    }
  35.  
     
  36.  
    @Override
  37.  
    public String toString() {
  38.  
    return "DemoDoctor [id=" + id + ", name=" + name + "]";
  39.  
    }
  40.  
     
  41.  
    }
  42.  
     

注意: 在后台采用对象接收参数时,Swagger自带的工具采用的是JSON传参,    测试时需要在参数上加入@RequestBody,正常运行采用form或URL提交时候请删除。

  1.  
    package com.zhongying.api.controller.app;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    import java.util.List;
  5.  
     
  6.  
    import javax.servlet.http.HttpServletRequest;
  7.  
     
  8.  
    import org.springframework.stereotype.Controller;
  9.  
    import org.springframework.web.bind.annotation.RequestBody;
  10.  
    import org.springframework.web.bind.annotation.RequestMapping;
  11.  
    import org.springframework.web.bind.annotation.RequestMethod;
  12.  
    import org.springframework.web.bind.annotation.RequestParam;
  13.  
    import org.springframework.web.bind.annotation.ResponseBody;
  14.  
     
  15.  
    import com.github.pagehelper.PageInfo;
  16.  
    import com.zhongying.api.exception.HttpStatus401Exception;
  17.  
    import com.zhongying.api.model.base.DemoDoctor;
  18.  
     
  19.  
    import io.swagger.annotations.Api;
  20.  
    import io.swagger.annotations.ApiImplicitParam;
  21.  
    import io.swagger.annotations.ApiImplicitParams;
  22.  
    import io.swagger.annotations.ApiOperation;
  23.  
     
  24.  
    /**
  25.  
    * 医生类(模拟)
  26.  
    * @author SUNF
  27.  
    */
  28.  
    @RequestMapping("/api/v1")
  29.  
    @Controller
  30.  
    @Api(value = "DoctorTestController-医生信息接口模拟")
  31.  
    public class DoctorTestController {
  32.  
     
  33.  
    /**
  34.  
    * 添加医生
  35.  
    *
  36.  
    * 在使用对象封装参数进行传参时,需要在该对象添加注解,将其注册到swagger中
  37.  
    * @link com.zhongying.api.model.base.DemoDoctor
  38.  
    *
  39.  
    * 注意: 在后台采用对象接收参数时,Swagger自带的工具采用的是JSON传参,
  40.  
    * 测试时需要在参数上加入@RequestBody,正常运行采用form或URL提交时候请删除。
  41.  
    *
  42.  
    * @param doctor 医生类对象
  43.  
    * @return
  44.  
    * @throws Exception
  45.  
    */
  46.  
    @ResponseBody
  47.  
    @RequestMapping(value="/doctor", method= RequestMethod.POST )
  48.  
    @ApiOperation(value="添加医生信息", notes="")
  49.  
    public String addDoctor(@RequestBody DemoDoctor doctor) throws Exception{
  50.  
    if(null == doctor || doctor.getId() == null){
  51.  
    throw new HttpStatus401Exception("添加医生失败","DT3388","未知原因","请联系管理员");
  52.  
    }
  53.  
    try {
  54.  
    System.out.println("成功----------->"+doctor.getName());
  55.  
    } catch (Exception e) {
  56.  
    throw new HttpStatus401Exception("添加医生失败","DT3388","未知原因","请联系管理员");
  57.  
    }
  58.  
     
  59.  
    return doctor.getId().toString();
  60.  
    }
  61.  
     
  62.  
    /**
  63.  
    * 删除医生
  64.  
    * @param doctorId 医生ID
  65.  
    * @return
  66.  
    */
  67.  
    @ResponseBody
  68.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.DELETE )
  69.  
    @ApiOperation(value="删除医生信息", notes="")
  70.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  71.  
    public String deleteDoctor(@RequestParam Integer doctorId){
  72.  
    if(doctorId > 2){
  73.  
    return "删除失败";
  74.  
    }
  75.  
    return "删除成功";
  76.  
    }
  77.  
     
  78.  
    /**
  79.  
    * 修改医生信息
  80.  
    * @param doctorId 医生ID
  81.  
    * @param doctor 医生信息
  82.  
    * @return
  83.  
    * @throws HttpStatus401Exception
  84.  
    */
  85.  
    @ResponseBody
  86.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.POST )
  87.  
    @ApiOperation(value="修改医生信息", notes="")
  88.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  89.  
    public String updateDoctor(@RequestParam Integer doctorId, @RequestBody DemoDoctor doctor) throws HttpStatus401Exception{
  90.  
    if(null == doctorId || null == doctor){
  91.  
    throw new HttpStatus401Exception("修改医生信息失败","DT3391","id不能为空","请修改");
  92.  
    }
  93.  
    if(doctorId > 5 ){
  94.  
    throw new HttpStatus401Exception("医生不存在","DT3392","错误的ID","请更换ID");
  95.  
    }
  96.  
    System.out.println(doctorId);
  97.  
    System.out.println(doctor);
  98.  
    return "修改成功";
  99.  
    }
  100.  
     
  101.  
    /**
  102.  
    * 获取医生详细信息
  103.  
    * @param doctorId 医生ID
  104.  
    * @return
  105.  
    * @throws HttpStatus401Exception
  106.  
    */
  107.  
    @ResponseBody
  108.  
    @RequestMapping(value="/doctor/{doctorId}", method= RequestMethod.GET )
  109.  
    @ApiOperation(value="获取医生详细信息", notes="仅返回姓名..")
  110.  
    @ApiImplicitParam(paramType="query", name = "doctorId", value = "医生ID", required = true, dataType = "Integer")
  111.  
    public DemoDoctor getDoctorDetail(@RequestParam Integer doctorId) throws HttpStatus401Exception{
  112.  
    System.out.println(doctorId);
  113.  
    if(null == doctorId){
  114.  
    throw new HttpStatus401Exception("查看医生信息失败","DT3390","未知原因","请联系管理员");
  115.  
    }
  116.  
    if(doctorId > 3){
  117.  
    throw new HttpStatus401Exception("医生不存在","DT3392","错误的ID","请更换ID");
  118.  
    }
  119.  
    DemoDoctor doctor = new DemoDoctor();
  120.  
    doctor.setId(1);
  121.  
    doctor.setName("测试员");
  122.  
    return doctor;
  123.  
    }
  124.  
     
  125.  
    /**
  126.  
    * 获取医生列表
  127.  
    * @param pageIndex 当前页数
  128.  
    * @param pageSize 每页记录数
  129.  
    * @param request
  130.  
    * @return
  131.  
    * @throws HttpStatus401Exception
  132.  
    */
  133.  
    @ResponseBody
  134.  
    @RequestMapping(value="/doctor", method= RequestMethod.GET )
  135.  
    @ApiOperation(value="获取医生列表", notes="目前一次全部取,不分页")
  136.  
    @ApiImplicitParams({
  137.  
    @ApiImplicitParam(paramType="header", name = "token", value = "token", required = true, dataType = "String"),
  138.  
    @ApiImplicitParam(paramType="query", name = "pageIndex", value = "当前页数", required = false, dataType = "String"),
  139.  
    @ApiImplicitParam(paramType="query", name = "pageSize", value = "每页记录数", required = true, dataType = "String"),
  140.  
    })
  141.  
    public PageInfo<DemoDoctor> getDoctorList(@RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
  142.  
    @RequestParam(value = "pageSize", required = false) Integer pageSize,
  143.  
    HttpServletRequest request) throws HttpStatus401Exception{
  144.  
     
  145.  
    String token = request.getHeader("token");
  146.  
    if(null == token){
  147.  
    throw new HttpStatus401Exception("没有权限","SS8888","没有权限","请查看操作文档");
  148.  
    }
  149.  
    if(null == pageSize){
  150.  
    throw new HttpStatus401Exception("每页记录数不粗安在","DT3399","不存在pageSize","请查看操作文档");
  151.  
    }
  152.  
     
  153.  
    DemoDoctor doctor1 = new DemoDoctor();
  154.  
    doctor1.setId(1);
  155.  
    doctor1.setName("测试员1");
  156.  
    DemoDoctor doctor2 = new DemoDoctor();
  157.  
    doctor2.setId(2);
  158.  
    doctor2.setName("测试员2");
  159.  
     
  160.  
    List<DemoDoctor> doctorList = new ArrayList<DemoDoctor>();
  161.  
    doctorList.add(doctor1);
  162.  
    doctorList.add(doctor2);
  163.  
    return new PageInfo<DemoDoctor>(doctorList);
  164.  
    }
  165.  
     
  166.  
     
  167.  
    }

增加header:

现在很多请求需要在header增加额外参数,可以参考getDoctorList()的做法,使用request接收。

Swagger UI使用指南的更多相关文章

  1. ABP框架 - Swagger UI 集成

    文档目录 本节内容: 简介 Asp.net Core 安装 安装Nuget包 配置 测试 Asp.net 5.x 安装 安装Nuget包 配置 测试 简介 来自它的网页:“...使用一个Swagger ...

  2. ABP理论学习之Swagger UI集成

    返回总目录 本篇目录 介绍 安装 安装Nuget包 配置 测试 介绍 从官方网站上可以看到:"启用了Swagger API,就可以获得交互式文档,生成和发现客户端SDK". 安装 ...

  3. ASP.NET Core 在 Swagger UI 中显示自定义的 Header Token

    Swagger 是个好东西,对于前后端分离的网站来说,不仅是提高前后端开发人员沟通效率的利器,也大大方便了后端人员测试 API.有时候,API 中可能需要在 Header 中设置认证参数,比如 aut ...

  4. 在Abp中集成Swagger UI功能

    在Abp中集成Swagger UI功能 1.安装Swashbuckle.Core包 通过NuGet将Swashbuckle.Core包安装到WebApi项目(或Web项目)中. 2.为WebApi方法 ...

  5. TP框架整合Swagger UI接口文档

    1.下载swagger ui:http://swagger.io/swagger-ui/: 2.在应用目录里新建一个目录xxx:如图 3.解压后把dist目录的所有文件拷贝到新建的目录里面: 4.在新 ...

  6. 使用 Swagger UI 与 Swashbuckle 创建 RESTful Web API 帮助文件

    作者:Sreekanth Mothukuru 2016年2月18日 本文旨在介绍如何使用常用的 Swagger 和 Swashbuckle 框架创建描述 Restful API 的交互界面,并为 AP ...

  7. Swagger PHP使用指南

    先说什么是Swagger, Swagger的使用目的是方便优美的呈现出接口API的各种定义, 生成API文档, 包括参数, 路径之类. 有时后端改了API的参数或者其他设置, 前端直接看这个Swagg ...

  8. gRPC helloworld service, RESTful JSON API gateway and swagger UI

    概述 本篇博文完整讲述了如果通过 protocol buffers 定义并启动一个 gRPC 服务,然后在 gRPC 服务上提供一个 RESTful JSON API 的反向代理 gateway,最后 ...

  9. ABP 用swagger UI测试API报401无权限访问问题

    问题描述: 当我们用swagger UI对Web API 进行测试时报401错误 我们点开GET /api/services/app/Role/GetAll,输入参数 点击Try it out!按钮, ...

随机推荐

  1. Linux下Flume的安装部署

    一.前置条件 Flume需要依赖JDK 1.8+,JDK安装方式见本仓库: Linux环境下JDK安装 二 .安装步骤 2.1 下载并解压 下载所需版本的Flume,这里我下载的是CDH版本的Flum ...

  2. Mac下安装redis5.0 与命令

    参考链接:https://blog.csdn.net/zyp1376308302/article/details/84257606 参开链接2:https://www.cnblogs.com/guan ...

  3. Python 爬虫从入门到进阶之路(十一)

    之前的文章我们介绍了一下 Xpath 模块,接下来我们就利用 Xpath 模块爬取<糗事百科>的糗事. 之前我们已经利用 re 模块爬取过一次糗百,我们只需要在其基础上做一些修改就可以了, ...

  4. [Qt]自定义表头实现过滤功能

    1. 写在前面 过滤功能源自项目上交互优化用户体验,在表头添加过滤符号实现过滤,替换以往在表格上方占用一行过滤项进行过滤. 2. 过滤提示 过滤提示就是三态图标(normal,hover,press) ...

  5. 并发编程-concurrent指南-原子操作类-AtomicLong

    可以用原子方式更新的 long 值.有关原子变量属性的描述,请参阅 java.util.concurrent.atomic 包规范.AtomicLong 可用在应用程序中(如以原子方式增加的序列号), ...

  6. Codeforces Gym101505G:Orchard Division(扫描线+线段树第k大)

    题目链接 题意 给出一个m*m的地图,上面有n个点,现在需要用一个自定义面积的矩形笼罩住恰好n/2个点,并且这个矩形需要有一个点在至少一个角落上,问这个矩形最小的面积是多少. 思路 有点类似于扫描线. ...

  7. myecliese加大内存

    加大内存代码 : -Xms512m -Xmx1024m -XX:PermSize=256M -XX:MaxPermSize=1024m

  8. python3.7 AES.MODE_ECB(128位) pkcs5padding 加密算法

    用惯用的写法总报TypeEerror错误,经过调试,总算成功啦,直接上代码 TypeError("Object type %s cannot be passed to C code" ...

  9. JS格式化JSON后的日期

    序列化后日期变成了 /Date(1494524134000+0800)\ 这种格式 不能正常显示了 但也不能为了这个吧所有服务的DateTime字段都改成String类型 于是找了一个JS的扩展方法来 ...

  10. 西门子S7-1200与 G120系列变频器USS通信

    西门子S7-1200 紧凑型PLC在当前的市场中有着广泛的应用,作为经常与SINAMICS G120系列变频器共同使用的PLC,其USS通信协议的使用一直在市场上有着非常广泛的应用.本文将主要介绍如何 ...