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实现抓取HTML网页并以PDF文件形式保存的方法
May 08 Python
使用Python编写Prometheus监控的方法
Oct 15 Python
python清除字符串前后空格函数的方法
Oct 21 Python
python实现五子棋游戏
Jun 18 Python
centos7之Python3.74安装教程
Aug 15 Python
Python sep参数使用方法详解
Feb 12 Python
python怎么调用自己的函数
Jul 01 Python
Python 实现简单的客户端认证
Jul 29 Python
Python环境搭建过程从安装到Hello World
Feb 05 Python
Python进度条的使用
May 17 Python
Python可视化动图组件ipyvizzu绘制惊艳的可视化动图
Apr 21 Python
Python 操作pdf pdfplumber读取PDF写入Exce
Aug 14 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 $_ENV为空的原因分析
2009/06/01 PHP
php 过滤英文标点符号及过滤中文标点符号代码
2014/06/12 PHP
单台服务器的PHP进程之间实现共享内存的方法
2014/06/13 PHP
学习php设计模式 php实现享元模式(flyweight)
2015/12/07 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
对laravel的csrf 防御机制详解,及form中csrf_token()的存在介绍
2019/10/24 PHP
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
2013/11/15 Javascript
jQuery 回调函数(callback)的使用和基础
2015/02/26 Javascript
JS扩展方法实例分析
2015/04/15 Javascript
JavaScript中判断数据类型的方法总结
2016/05/24 Javascript
Ajax实现不刷新取最新商品
2017/03/01 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
一步快速解决微信小程序中textarea层级太高遮挡其他组件
2019/03/04 Javascript
详解如何更好的使用module vuex
2019/03/27 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
Python采用socket模拟TCP通讯的实现方法
2014/11/19 Python
Python中atexit模块的基本使用示例
2015/07/08 Python
python和bash统计CPU利用率的方法
2015/07/10 Python
Python 列表排序方法reverse、sort、sorted详解
2016/01/22 Python
Python中关于Sequence切片的下标问题详解
2017/06/15 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
java中两个byte数组实现合并的示例
2018/05/09 Python
详细介绍Python进度条tqdm的使用
2019/07/31 Python
python在不同条件下的输入与输出
2020/02/13 Python
jupyter note 实现将数据保存为word
2020/04/14 Python
Ted Baker美国官网:英国时尚品牌
2018/10/29 全球购物
洲际酒店集团英国官网:IHG英国
2019/07/10 全球购物
天逸系统(武汉)有限公司Java笔试题
2015/12/29 面试题
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
在职人员函授期间自我评价分享
2013/11/08 职场文书
结婚纪念日感言
2015/08/01 职场文书
Python3接口性能测试实例代码
2021/06/20 Python
制作能在nginx和IIS中使用的ssl证书
2021/06/21 Servers
用Python可视化新冠疫情数据
2022/01/18 Python
MySQ InnoDB和MyISAM存储引擎介绍
2022/04/26 MySQL