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 相关文章推荐
linux环境下安装pyramid和新建项目的步骤
Nov 27 Python
Python的Bottle框架中获取制定cookie的教程
Apr 24 Python
浅析Python中的多重继承
Apr 28 Python
简单介绍使用Python解析并修改XML文档的方法
Oct 15 Python
简单掌握Python的Collections模块中counter结构的用法
Jul 07 Python
python3 pillow生成简单验证码图片的示例
Sep 19 Python
python实现多线程行情抓取工具的方法
Feb 28 Python
使用Python实现一个栈判断括号是否平衡
Aug 23 Python
使用Python制作简单的小程序IP查看器功能
Apr 16 Python
Python 中使用 PyMySQL模块操作数据库的方法
Nov 10 Python
Python3中的f-Strings增强版字符串格式化方法
Mar 04 Python
使用Keras实现简单线性回归模型操作
Jun 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面向对象全攻略 (二) 实例化对象 使用对象成员
2009/09/30 PHP
php性能优化分析工具XDebug 大型网站调试工具
2011/05/22 PHP
php去除换行符的方法小结(PHP_EOL变量的使用)
2013/02/16 PHP
解决PHP上传非标准格式的图片pjpeg失败的方法
2017/03/12 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
javascript得到XML某节点的子节点个数的脚本
2008/10/11 Javascript
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
JQuery的一些小应用收集
2010/03/27 Javascript
jQuery-serialize()输出序列化form表单值的方法
2012/12/26 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
js光标定位文本框回车表单提交问题的解决方法
2015/05/11 Javascript
Bootstrap每天必学之按钮(Button)插件
2016/04/25 Javascript
vue.js树形组件之删除双击增加分支实例代码
2017/02/28 Javascript
vue实现todolist单页面应用
2017/04/11 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
2017/05/22 Javascript
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
2017/09/07 jQuery
javascript变量提升和闭包理解
2018/03/12 Javascript
使用JSON格式提交数据到服务端的实例代码
2018/04/01 Javascript
js+canvas实现简单扫雷小游戏
2021/01/22 Javascript
keep-alive不能缓存多层级路由菜单问题解决
2020/03/10 Javascript
tensorflow实现简单的卷积神经网络
2018/05/24 Python
Linux下python3.7.0安装教程
2018/07/30 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
python基于paramiko将文件上传到服务器代码实现
2019/07/08 Python
不可轻视HTML5!App三年内将被html5顶替彻底消失
2015/11/18 HTML / CSS
如果重写了对象的equals()方法,需要考虑什么
2014/11/02 面试题
应届生体育教师自荐信
2013/10/03 职场文书
《美丽的丹顶鹤》教学反思
2014/04/22 职场文书
《莫泊桑拜师》教学反思
2014/04/23 职场文书
人代会标语
2014/06/30 职场文书
村干部群众路线教育活动对照检查材料
2014/10/01 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
解决Go gorm踩过的坑
2021/04/30 Golang