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的Django框架中实现Hacker News的一些功能
Apr 17 Python
python多线程方式执行多个bat代码
Jun 07 Python
Swift 3.0在集合类数据结构上的一些新变化总结
Jul 11 Python
Python学习入门之区块链详解
Jul 25 Python
Python 通过requests实现腾讯新闻抓取爬虫的方法
Feb 22 Python
Django框架 Pagination分页实现代码实例
Sep 04 Python
Pycharm创建项目时如何自动添加头部信息
Nov 14 Python
基于Tensorflow批量数据的输入实现方式
Feb 05 Python
Python模块/包/库安装的六种方法及区别
Feb 24 Python
Python如何实现后端自定义认证并实现多条件登陆
Jun 22 Python
python 实现客户端与服务端的通信
Dec 23 Python
Python的flask接收前台的ajax的post数据和get数据的方法
Apr 12 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结合正则获取字符串中数字
2015/06/19 PHP
PHP实现基于面向对象的mysqli扩展库增删改查操作工具类
2017/07/18 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
prototype 源码中文说明之 prototype.js
2006/09/22 Javascript
枚举JavaScript对象的函数
2006/12/22 Javascript
iframe 自适应高度[在IE6 IE7 FF下测试通过]
2009/04/13 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
js获取URL的参数的方法(getQueryString)示例
2013/09/29 Javascript
JS正则验证邮箱的格式详细介绍
2013/11/19 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
JS实现跟随鼠标立体翻转图片的方法
2015/05/04 Javascript
JavaScript中各种引用类型的常用操作方法小结
2016/05/05 Javascript
微信小程序  action-sheet详解及实例代码
2016/11/09 Javascript
JS简单实现移动端日历功能示例
2016/12/28 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
2017/02/15 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
2017/03/08 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
vue的全局提示框组件实例代码
2018/02/26 Javascript
2种在vue项目中使用百度地图的简单方法
2018/09/28 Javascript
jsonp格式前端发送和后台接受写法的代码详解
2019/11/07 Javascript
基于canvasJS在PHP中制作动态图表
2020/05/30 Javascript
[53:13]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第三场 1月18日
2021/03/11 DOTA
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python中plot实现即时数据动态显示方法
2018/06/22 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
python 实现敏感词过滤的方法
2019/01/21 Python
Python实现迪杰斯特拉算法过程解析
2020/09/18 Python
在校大学生个人的自我评价
2014/02/13 职场文书
食品科学与工程专业毕业生求职信范文
2014/07/21 职场文书
诚实守信道德模范事迹材料
2014/08/15 职场文书
严以修身专题学习研讨会发言材料
2015/11/09 职场文书
2016年少先队活动总结
2016/04/06 职场文书
小学生作文写作技巧100例,非常实用!
2019/07/08 职场文书
祝福语集锦:给妹妹结婚的祝福语
2019/12/18 职场文书
pytorch 带batch的tensor类型图像显示操作
2021/05/20 Python