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中的循环语句的用法
Apr 09 Python
初步介绍Python中的pydoc模块和distutils模块
Apr 13 Python
Windows下Python的Django框架环境部署及应用编写入门
Mar 10 Python
python访问抓取网页常用命令总结
Apr 11 Python
python之PyMongo使用总结
May 26 Python
python pandas修改列属性的方法详解
Jun 09 Python
使用 Python 实现微信群友统计器的思路详解
Sep 26 Python
解决Pycharm 包已经下载,但是运行代码提示找不到模块的问题
Aug 31 Python
python绘制彩虹图
Dec 16 Python
Python文字截图识别OCR工具实例解析
Mar 05 Python
python3实现将json对象存入Redis以及数据的导入导出
Jul 16 Python
ASP.NET Core中的配置详解
Feb 05 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
iis下php mail函数的sendmail配置方法(官方推荐)
2012/04/25 PHP
PHP 万年历实现代码
2012/10/18 PHP
PHP常量使用的几个需要注意的地方(谨慎使用PHP中的常量)
2014/09/12 PHP
php制作动态随机验证码
2015/02/12 PHP
PHP使用内置dir类实现目录遍历删除
2015/03/31 PHP
浅谈php的优缺点
2015/07/14 PHP
PHP多进程之pcntl_fork的实例详解
2017/10/15 PHP
PHP使用PDO抽象层获取查询结果的方法示例
2018/05/10 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
你可能不再需要JQUERY
2021/03/09 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
JavaScript中使用Object.create()创建对象介绍
2014/12/30 Javascript
animate 实现滑动切换效果【实例代码】
2016/05/05 Javascript
jquery.cookie.js的介绍与使用方法
2017/02/09 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
2017/12/14 Javascript
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
学习Vue组件实例
2018/04/28 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
node和vue实现商城用户地址模块
2018/12/05 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
javascript利用键盘控制小方块的移动
2020/04/20 Javascript
详解Python中find()方法的使用
2015/05/18 Python
Python2.x中文乱码问题解决方法
2015/06/02 Python
Python基于回溯法子集树模板解决选排问题示例
2017/09/07 Python
Python 判断 有向图 是否有环的实例讲解
2018/02/01 Python
python opencv将图片转为灰度图的方法示例
2019/07/31 Python
在OpenCV里使用Camshift算法的实现
2019/11/22 Python
Python json转字典字符方法实例解析
2020/04/13 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
2015年七七事变78周年纪念活动方案
2015/05/06 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
2016年社区文体活动总结
2016/04/06 职场文书