Spring http服务远程调用实现过程解析


Posted in Python onJune 11, 2020

最近公司有个新的需求,写了一个接口,想要把服务暴露出去,但是这个服务所在的进程是非web项目,(可以理解成schedule/batch等进程项目),所以没有tomcat等容器,而且只有这一个服务,无论是加dubbo服务还是加tomcat等容器都显得复杂了。那么应该如何将服务暴露出去?

经过网上搜索后,最终解决问题,记录在此。

为了快速搭建,使用springboot来搭建项目:

项目结构如图:

Spring http服务远程调用实现过程解析

首先需要创建一个接口,服务的提供者和服务的调用方都依赖这个模块。

package com.xiazhi.spring.service.api;

import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;

/**
 * @author 赵帅
 * @date 2020/6/8
 */
public interface IUserService {

  /**
   * 获取姓名
   * @return 姓名
   */
  String getName();

  /**
   * 根据姓名获取年龄
   * @param name 姓名
   * @return 年龄
   */
  @NotNull
  Integer getAge(@Nullable String name);
}

然后在service模块中,实现接口作为服务的提供方,需要依赖的jar包有:

<dependencies>
    <dependency>
      <groupId>com.xiazhi</groupId>
      <artifactId>spring-service-api</artifactId>
      <version>${project.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
  </dependencies>

配置文件需要加上:

spring.main.web-application-type=none

实现接口:

package com.xiazhi.spring.service.impl;

import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.stereotype.Service;

/**
 * @author 赵帅
 * @date 2020/6/8
 */
@Service
public class UserServiceImpl implements IUserService {

  @Override
  public String getName() {
    return "张一";
  }

  @Override
  @NotNull
  public Integer getAge(@Nullable String name) {
    if ("".equals(name)) {
      return 10;
    }
    return 18;
  }
}

暴露服务:

package com.xiazhi.spring.service.config;

import com.sun.net.httpserver.HttpHandler;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter;
import org.springframework.remoting.support.SimpleHttpServerFactoryBean;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 赵帅
 * @date 2020/6/8
 */
@Configuration
public class HttpInvokerConfiguration {

  private final IUserService userService;
  private final TaskExecutor taskExecutor;

  public HttpInvokerConfiguration(IUserService userService, TaskExecutor taskExecutor) {
    this.userService = userService;
    this.taskExecutor = taskExecutor;
  }

  /**
   * 将IUserService服务暴露出去
   */
  @Bean
  public SimpleHttpInvokerServiceExporter serviceExporter() {
    SimpleHttpInvokerServiceExporter exporter = new SimpleHttpInvokerServiceExporter();
    exporter.setService(userService);
    exporter.setServiceInterface(IUserService.class);
    return exporter;
  }

  /**
   * 为暴露的服务启用http服务
   * @return httpServer工厂类
   */
  @Bean
  public SimpleHttpServerFactoryBean serverFactoryBean() {
    SimpleHttpServerFactoryBean factoryBean = new SimpleHttpServerFactoryBean();
    Map<String, HttpHandler> map = new HashMap<>(2);
    factoryBean.setContexts(map);
    factoryBean.setPort(9999);
    factoryBean.setExecutor(taskExecutor);
    return factoryBean;
  }
}

启动服务。

然后是服务的调用方,依赖有:

<dependencies>
    <dependency>
      <groupId>com.xiazhi</groupId>
      <artifactId>spring-service-api</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>

配置文件:

package com.xiazhi.spring.config;

import com.xiazhi.spring.service.api.IUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;

/**
 * @author 赵帅
 * @date 2020/6/8
 */
@Configuration
public class HttpServiceConfiguration {

  /**
   * 使用http代理工厂调用服务
   * @return http代理工厂创建代理对象
   */
  @Bean
  public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
    HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean();
    factoryBean.setServiceUrl("http://localhost:9999/userService");
    factoryBean.setServiceInterface(IUserService.class);
    return factoryBean;
  }
}

使用接口,调用方法:

package com.xiazhi.spring.controller;

import com.xiazhi.spring.service.api.IUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 赵帅
 * @date 2020/6/8
 */
@RestController
public class UserController {

  private final IUserService userService;

  public UserController(IUserService userService) {
    this.userService = userService;
  }

  @GetMapping("/test")
  public String test() {
    String name = userService.getName();
    Integer age = userService.getAge(null);
    System.out.println(String.format("姓名:[%s],age:[%s]", name, age));
    return name;
  }
}

运行,调用test路径测试调用结果。

项目完整结构:

Spring http服务远程调用实现过程解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之画圈还不简单吗?
Sep 20 Python
Python入门必须知道的11个知识点
Mar 21 Python
pycharm设置注释颜色的方法
May 23 Python
django中ORM模型常用的字段的使用方法
Mar 05 Python
Python实现的银行系统模拟程序完整案例
Apr 12 Python
python 矢量数据转栅格数据代码实例
Sep 30 Python
opencv-python 提取sift特征并匹配的实例
Dec 09 Python
python无序链表删除重复项的方法
Jan 17 Python
在tensorflow中实现去除不足一个batch的数据
Jan 20 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
Jan 25 Python
基于python实现上传文件到OSS代码实例
May 09 Python
Python文件的操作示例的详细讲解
Apr 08 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 #Python
python怎么提高计算速度
Jun 11 #Python
Python 实现自动登录+点击+滑动验证功能
Jun 10 #Python
Python函数参数定义及传递方式解析
Jun 10 #Python
什么是python类属性
Jun 10 #Python
基于SQLAlchemy实现操作MySQL并执行原生sql语句
Jun 10 #Python
浅谈Python中的模块
Jun 10 #Python
You might like
用php+mysql一个名片库程序
2006/10/09 PHP
php allow_url_include的应用和解释
2010/04/22 PHP
Look And Say 序列php实现代码
2011/05/22 PHP
关于php curl获取301或302转向的网址问题的解决方法
2011/06/02 PHP
laravel框架中表单请求类型和CSRF防护实例分析
2019/11/23 PHP
IE中jscript/javascript的条件编译
2006/09/07 Javascript
js中将URL中的参数提取出来作为对象的实现代码
2011/08/16 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
jQuery模仿京东/天猫商品左侧分类导航菜单效果
2016/06/29 Javascript
web 屏蔽BackSpace键实例代码
2016/12/24 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
Vue select 绑定动态变量的实例讲解
2020/10/22 Javascript
vue 图片裁剪上传组件的实现
2020/11/12 Javascript
Python日志模块logging简介
2015/04/13 Python
python实现将汉字转换成汉语拼音的库
2015/05/05 Python
Python中的ctime()方法使用教程
2015/05/22 Python
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
Flask之请求钩子的实现
2018/12/23 Python
python统计字符的个数代码实例
2020/02/07 Python
python编写扎金花小程序的实例代码
2021/02/23 Python
纯css3制作的火影忍者写轮眼开眼至轮回眼及进化过程实例
2014/11/11 HTML / CSS
塔吉特百货公司官网:Target
2017/04/27 全球购物
澳大利亚100%丝绸多彩度假装商店:TheSwankStore
2019/09/04 全球购物
上海中网科技笔试题
2012/02/19 面试题
成人高等教育毕业生自我鉴定
2013/10/22 职场文书
医药代表个人的求职信分享
2013/12/08 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
汽车检测与维修专业求职信
2014/07/04 职场文书
街道务虚会发言材料
2014/10/20 职场文书
2014年学生会干事工作总结
2014/11/07 职场文书
高三英语复习计划
2015/01/19 职场文书
Nginx配置SSL证书出错解决方案
2021/03/31 Servers
Python内置数据结构列表与元组示例详解
2021/08/04 Python
python中urllib包的网络请求教程
2022/04/19 Python
python和anaconda的区别
2022/05/06 Python
SQL Server2019安装的详细步骤实战记录(亲测可用)
2022/06/10 SQL Server