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改变日志(logging)存放位置的示例
Mar 27 Python
python监控文件或目录变化
Jun 07 Python
python分析作业提交情况
Nov 22 Python
Python使用matplotlib实现绘制自定义图形功能示例
Jan 18 Python
python requests 库请求带有文件参数的接口实例
Jan 03 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
Jun 17 Python
python 计算数据偏差和峰度的方法
Jun 29 Python
Ubuntu+python将nii图像保存成png格式
Jul 18 Python
使用TensorFlow实现简单线性回归模型
Jul 19 Python
pandas条件组合筛选和按范围筛选的示例代码
Aug 26 Python
scikit-learn线性回归,多元回归,多项式回归的实现
Aug 29 Python
Python自动发送和收取邮件的方法
Aug 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
Thinkphp模板中使用自定义函数的方法
2012/09/23 PHP
php中利用explode函数分割字符串到数组
2014/02/08 PHP
推荐dojo学习笔记
2007/03/24 Javascript
Extjs中ComboBox加载并赋初值的实现方法
2012/03/22 Javascript
angularjs指令中的compile与link函数详解
2014/12/06 Javascript
javascript批量修改文件编码格式的方法
2015/01/27 Javascript
JavaScript中用toString()方法返回时间为字符串
2015/06/12 Javascript
jQuery实现简易的天天爱消除小游戏
2015/10/16 Javascript
Jquery时间轴特效(三种不同类型)
2015/11/02 Javascript
浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
2016/01/14 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
2016/06/07 Javascript
JavaScript仿flash遮罩动画效果
2016/06/15 Javascript
Javascript动画效果(1)
2016/10/11 Javascript
Angular ui.bootstrap.pagination分页
2017/01/20 Javascript
基于JavaScript实现复选框的全选和取消全选
2017/02/09 Javascript
原生js实现简单的Ripple按钮实例代码
2017/03/24 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
JS和jQuery通过this获取html标签中的属性值(实例代码)
2017/09/11 jQuery
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
Python pyinotify日志监控系统处理日志的方法
2018/03/08 Python
Python3实现的爬虫爬取数据并存入mysql数据库操作示例
2018/06/06 Python
对Python闭包与延迟绑定的方法详解
2019/01/07 Python
python 格式化输出百分号的方法
2019/01/20 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
在pycharm中debug 实时查看数据操作(交互式)
2020/06/09 Python
新加坡最佳婴儿用品店:Mamahood.com.sg
2018/08/26 全球购物
家居设计专业个人自荐信范文
2013/11/26 职场文书
组织鉴定材料
2014/06/02 职场文书
宣传活动总结范文
2014/07/01 职场文书
小班下学期个人总结
2015/02/12 职场文书
党性教育心得体会(共6篇)
2016/01/21 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书
常用的MongoDB查询语句的示例代码
2021/07/25 MongoDB