webservice

一 什么是webservice

web服务:部署在网络上的一个可访问的应用程序,主要对外提供一些业务接口。

日常例子:天气预告、查询手机的归属地。

二 webservice组成

说明:

  • 注册方:服务提供者首先要在注册服务器上注册服务的接口、方法信息、访问地址等等。

  • 服务提供者:服务的实现方

  • 服务消费者:调用服务的一方,称为服务的客户端,指的是一切调用服务的消费者,例如,app、网站、组件 、controller等等。

三 传统的webservice的技术标准(了解)

1. xml文档 数据格式以xml数据交互,优点:平台无关性和语言无关性。是以远程方法调用(RPC).

2. 通讯协议 SOAP协议 simple object access protocal 简单对象访问协议,相对http性能更好,可以传输对象。

3. wsdl web服务描述语言(xml),主要的作用描述web服务(说明书)

技术场景: Dubbo微服务(阿里开源)

四 restfult服务(重点)

1. json数据交互 不是远程方法调用

2. http协议

3. 无wsdl文件

技术场景: Springboot+Springcloud分布式应用开发

五 使用CXF开发Webservice

Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。Apache CXF 是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2XML/HTTPRESTful 或者CORBA

开发步骤:

(1)开发web应用

(2)导入cxf3类库

(3)配置web.xml,cxf的中央控制器。cxf是基于MVC结构

  <!-- CXF 中央控制器 -->
  <servlet>
      <servlet-name>cxfServlet</servlet-name>
      <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
     <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>cxfServlet</servlet-name>
      <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

(4)实现业务功能

  • 业务接口

@WebService  //表示当前是一个可发布的接口
public interface ProductService {
    public List<Product> findAllProducts();
}
  • 业务实现类

public class ProductServiceImpl implements ProductService {
    @Override
    public List<Product> findAllProducts() {
        List<Product> list = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list.add(new Product(i,"TCL电视"+i,5000D,"广州"));
        }
        return list;
    }
}

(5)以spring方式发布webservice

<!-- 以spring方式发布应用程序接口 -->
<jaxws:endpoint id="productServiceImpl" 
                implementor="com.gec.ws.service.ProductServiceImpl"
                address="/productService"></jaxws:endpoint>

(6)访问Websevice的wsdl文件

地址:http://localhost:8080/services/productService?wsdl

(7) 客户端访问

  • spring方式(代理方式)

/**
 * 远程方法调用,spring方式
 * 远程方法调用,边界条件:以jvm来区分
 */
public class WebServiceSpringTest {

    public static void main(String[] args) {
        //要获取spring创建的webservice客户端
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取的是代理接口实例
        ProductService productService = (ProductService) context.getBean("productService");
        List<Product> list = productService.findAllProducts(); //方法的远程调用
        for (Product product : list) {
            System.out.println(product.getNanme());
        }
    }
}
  • 代理方式


/**
 * 不依赖于spring
 * 使用代理方式创建远程访问的客户端
 */
public class ProxyTest {
    public static void main(String[] args) {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(ProductService.class); //设置代理接口类型
        factory.setAddress("http://localhost:8080/services/productService");
        ProductService productService = (ProductService) factory.create();
        List<Product> list = productService.findAllProducts(); //方法的远程调用
        for (Product product : list) {
            System.out.println(product.getNanme());
        }
    }
}

六 Restful服务

Restful服务指的是将网络上的资源分配一个唯一标识(URI),只需要获取了该资源的唯一标识就可以对这个资源进行操作(增删改查)。基本都是以json进行交互。在SSM项目中,一般会使用springmvc的controller对外发布业务数据。

restfule服务常用的操作类别:

GET(查询) POST(创建) PUT(编辑) DELETE(删除)

(1) 完整定义restful服务接口

@Api(tags = "ItemController",description = "商品后台管理服务")
@RestController
public class ItemController {
    @Autowired
    public ItemService itemService;

    @ApiOperation("查询所有商品信息")
    @GetMapping("/findAll")
    public List<Items> findAll() {
        return itemService.findAll();
    }

    @ApiOperation("根据唯一标识查询唯一商品信息")
    @GetMapping("/findOne/{id}")
    public Items findOne(@PathVariable int id) {
        return itemService.findOne(id);
    }

    @ApiOperation("添加商品信息")
    @PostMapping("/addItems")
    public RespBean addItems(@ApiParam("商品对象") @RequestBody Items items) {
        System.out.println(items.getId());
        System.out.println(items.getName());
        try{
            itemService.addItem(items);
            return RespBean.ok("添加成功",items);
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("添加失败");
        }

    }

    @ApiOperation("编辑商品信息")
    @PutMapping("/updateItems")
    public RespBean updateItems(@ApiParam("商品对象") @RequestBody Items items) {
        System.out.println(items.getId());
        System.out.println(items.getName());
        try{
            itemService.updateItem(items);
            return RespBean.ok("编辑成功",items);
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("编辑失败");
        }

    }

    @ApiOperation("根据商品唯一标识删除商品信息")
    @DeleteMapping("/deleteItems/{id}")
    public RespBean deleteItems(@PathVariable int id) {
        try{
            itemService.deleteItem(id);
            return RespBean.ok("删除成功");
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("删除失败");
        }

    }
}

(2) 响应消息类

/**
 * 消息响应类
 */
public class RespBean {
    private Integer code;  //自定义响应码: 200正常   500错误
    private String message;
    private Object data;  //返回的数据

    public static RespBean ok(String message) {
        return new RespBean(200,message);
    }

    public static RespBean ok(String message,Object data) {
        return new RespBean(500,message,data);
    }

    public static RespBean error(String message) {
        return new RespBean(200,message);
    }

    public static RespBean error(String message,Object data) {
        return new RespBean(500,message,data);
    }

    private RespBean(Integer code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    private RespBean(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

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

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

七 服务的测试

(1)Postman工具

添加测试:

修改测试

(2)Swagger2在线文档

实现步骤:

  • 添加swagger依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.7.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.7.0</version>
</dependency>
  • swagger配置

/**
 * Swagger2API文档的配置
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //为当前包下controller生成API文档
                .apis(RequestHandlerSelectors.basePackage("com.gec.ssm.controller"))
                //为有@Api注解的Controller生成API文档
//                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
                //为有@ApiOperation注解的方法生成API文档
//                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SwaggerUI演示")
                .description("商品查询服务")
                .contact("陈志凌")
                .version("1.0")
                .build();
    }
}
  • swagger2的常用注解

主要有三个常用注解:使用于类、方法、参数列表的注解

@Api(tags = "ItemController",description = "商品后台管理服务")
@RestController
public class ItemController {
    @Autowired
    public ItemService itemService;

    @ApiOperation("查询所有商品信息")
    @GetMapping("/findAll")
    public List<Items> findAll() {
        return itemService.findAll();
    }

    @ApiOperation("根据唯一标识查询唯一商品信息")
    @GetMapping("/findOne/{id}")
    public Items findOne(@PathVariable int id) {
        return itemService.findOne(id);
    }

    @ApiOperation("添加商品信息")
    @PostMapping("/addItems")
    public RespBean addItems(@ApiParam("商品对象") @RequestBody Items items) {
        System.out.println(items.getId());
        System.out.println(items.getName());
        try{
            itemService.addItem(items);
            return RespBean.ok("添加成功",items);
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("添加失败");
        }

    }

    @ApiOperation("编辑商品信息")
    @PutMapping("/updateItems")
    public RespBean updateItems(@ApiParam("商品对象") @RequestBody Items items) {
        System.out.println(items.getId());
        System.out.println(items.getName());
        try{
            itemService.updateItem(items);
            return RespBean.ok("编辑成功",items);
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("编辑失败");
        }

    }

    @ApiOperation("根据商品唯一标识删除商品信息")
    @DeleteMapping("/deleteItems/{id}")
    public RespBean deleteItems(@PathVariable int id) {
        try{
            itemService.deleteItem(id);
            return RespBean.ok("删除成功");
        } catch (Exception ex){
            ex.printStackTrace();
            return RespBean.error("删除失败");
        }

    }
}

效果:

八 总结两种服务区别

说明:

  • RPC remote process call 远程方法调用

  • 以XML文档进行方法调用的交互

  • 比较复杂,实现较繁琐

  • 采用SOAP协议

  • 客户端要引用服务端的代理接口类型,作为方法的远程调用

  • 应用场景:适用于同构应用比较多

  • 访问性能较好

  • 微服务的发展方向:Dubbo

说明:

  • 数据交互采用json格式

  • 使用http协议

  • 访问性能较差

  • 同构和异构应用都可以使用,应用范围广泛

  • 仅仅是客户端对远程资源的定位操作(增删改查),并不是远程方法的调用

  • 微服务的发展方向:springboot+springcloud

九 RestTemplate访问Restful服务

JavaWeb应用的controller调用:

@Controller
public class ItemWebController {

    @Autowired
    private RestTemplate restTemplate;

    public String baseURL = "http://localhost:8088/";

    @GetMapping("/queryItems")
    public ModelAndView queryItems() {
        //泛型:LinkedHashMap
        List list = restTemplate.getForObject(baseURL+"findAll", List.class);
        System.out.println(list);

        ModelAndView mv = new ModelAndView();
        mv.addObject("itemList",list);
        mv.setViewName("itemlist");
        return mv;
    }

    @GetMapping("/findItemById")
    public ModelAndView findItemById(int id) {
        ItemEntity itemEntity = restTemplate.getForObject(baseURL+"findOne/"+id, ItemEntity.class);
        ModelAndView mv = new ModelAndView();
        mv.addObject("item",itemEntity);
        mv.setViewName("editItem");
        return mv;
    }

    @PostMapping("/updateItemsSubmit")
    public String  updateItemsSubmit(ItemEntity itemEntity) {
        restTemplate.put(baseURL+"updateItems",itemEntity);
        return "redirect:/queryItems";
    }

    @PostMapping("/addItemsSubmit")
    public String addItemsSubmit(ItemEntity itemEntity) {
        RespBean respBean = restTemplate.postForObject(baseURL+"addItems",itemEntity, RespBean.class);
        if (respBean.getCode()==200){
            return "redirect:/queryItems";
        } else {
            return "addItem";
        }
    }

    @GetMapping("/deleteItem")
    public String deleteItem(int id) {
        restTemplate.delete(baseURL+"deleteItems/"+id);
        return "redirect:/queryItems";
    }

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值