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算法学习之桶排序算法实例(分块排序)
Dec 18 Python
python字符串连接方法分析
Apr 12 Python
Python中matplotlib中文乱码解决办法
May 12 Python
Python双精度浮点数运算并分行显示操作示例
Jul 21 Python
Python Image模块基本图像处理操作小结
Apr 13 Python
python 多进程并行编程 ProcessPoolExecutor的实现
Oct 11 Python
用Python去除图像的黑色或白色背景实例
Dec 12 Python
python识别验证码图片实例详解
Feb 17 Python
openCV提取图像中的矩形区域
Jul 21 Python
python mock测试的示例
Oct 19 Python
Python 利用flask搭建一个共享服务器的步骤
Dec 05 Python
Python操作CSV格式文件的方法大全
Jul 15 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批量生成随机用户名
2008/07/10 PHP
php &amp;&amp; 逻辑与运算符使用说明
2010/03/04 PHP
PHP按行读取文件时删除换行符的3种方法
2014/05/04 PHP
php冒泡排序与快速排序实例详解
2015/12/07 PHP
刷新页面实现方式总结(HTML,ASP,JS)
2008/11/13 Javascript
jQuery DOM操作小结与实例
2010/01/07 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
2010/11/14 Javascript
jQuery.event兼容各浏览器的event详细解析
2013/12/18 Javascript
JS中Date日期函数中的参数使用介绍
2014/01/02 Javascript
Javascript基础教程之for循环
2015/01/18 Javascript
jQuery实现仿QQ在线客服效果的滚动层代码
2015/10/15 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
用原生js统计文本行数的简单示例
2016/08/19 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
js原生之焦点图转换加定时器实例
2016/12/12 Javascript
AngularJS实现使用路由切换视图的方法
2017/01/24 Javascript
深入理解JavaScript中的尾调用(Tail Call)
2017/02/07 Javascript
JavaScript中object和Object的区别(详解)
2017/02/27 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
2017/12/07 Javascript
在vue-cli项目中使用bootstrap的方法示例
2018/04/21 Javascript
vue2.0 下拉框默认标题设置方法
2018/08/22 Javascript
angularJs select绑定的model取不到值的解决方法
2018/10/08 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
python采用getopt解析命令行输入参数实例
2014/09/30 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
numpy中的meshgrid函数的使用
2019/07/31 Python
Django如何批量创建Model
2020/09/01 Python
怎样让char类型的东西转换成int类型
2013/12/09 面试题
信息管理与信息系统专业求职信
2014/06/21 职场文书
在职党员进社区活动总结
2014/07/05 职场文书
年终晚会活动方案
2014/08/21 职场文书
2014年残联工作总结
2014/11/21 职场文书
体育活动总结
2015/02/04 职场文书
CSS中em的正确打开方式详解
2021/04/08 HTML / CSS
使用Springboot实现健身房管理系统
2021/07/01 Java/Android
MySql数据库触发器使用教程
2022/06/01 MySQL