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 相关文章推荐
pytyon 带有重复的全排列
Aug 13 Python
win7安装python生成随机数代码分享
Dec 27 Python
Python学习笔记之常用函数及说明
May 23 Python
让 python 命令行也可以自动补全
Nov 30 Python
Python实现的简单文件传输服务器和客户端
Apr 08 Python
简单了解Python下用于监视文件系统的pyinotify包
Nov 13 Python
用ReactJS和Python的Flask框架编写留言板的代码示例
Dec 19 Python
python3连接MySQL数据库实例详解
May 24 Python
对Python 内建函数和保留字详解
Oct 15 Python
Python 虚拟空间的使用代码详解
Jun 10 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
Mar 18 Python
PyPDF2读取PDF文件内容保存到本地TXT实例
May 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中的观察者模式
2010/03/24 PHP
解析dedeCMS验证码的实现代码
2013/06/07 PHP
ThinkPHP5&amp;5.1框架关联模型分页操作示例
2019/08/03 PHP
laravel-admin的多级联动方法
2019/09/30 PHP
PHP 8新特性简介
2020/08/18 PHP
jQuery去掉字符串起始和结尾的空格(多种方法实现)
2013/04/01 Javascript
利用js 进行输入框自动匹配字符的小例子
2013/06/29 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
Jquery实现仿京东商城省市联动菜单
2015/11/19 Javascript
浅谈String.valueOf()方法的使用
2016/06/06 Javascript
JS完成画圆圈的小球
2017/03/07 Javascript
把JavaScript代码改成ES6语法不完全指南(分享)
2017/09/10 Javascript
详解node.js 下载图片的 2 种方式
2018/03/02 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
layui实现多图片上传并限制上传的图片数量
2019/09/26 Javascript
package.json中homepage属性的作用详解
2020/03/11 Javascript
详解React的回调渲染模式
2020/09/10 Javascript
js实现验证码干扰(动态)
2021/02/23 Javascript
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
Python实现获取当前目录下文件名代码详解
2020/03/10 Python
jupyter notebook 调用环境中的Keras或者pytorch教程
2020/04/14 Python
使用pymysql查询数据库,把结果保存为列表并获取指定元素下标实例
2020/05/15 Python
Python使用for生成列表实现过程解析
2020/09/22 Python
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
英国领先的在线高尔夫商店:Scottsdale Golf
2019/08/26 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
幼儿园安全检查制度
2014/01/30 职场文书
酒店开业策划方案
2014/06/02 职场文书
会计学专业自荐信
2014/06/25 职场文书
男方家长婚礼答谢词
2015/09/29 职场文书
2016年学校安全教育月活动总结
2016/04/06 职场文书
解析探秘fescar分布式事务实现原理
2022/02/28 Java/Android