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网络编程学习笔记(四):域名系统
Jun 09 Python
python关闭windows进程的方法
Apr 18 Python
在Python中处理日期和时间的基本知识点整理汇总
May 22 Python
Python基于PycURL实现POST的方法
Jul 25 Python
python生成器与迭代器详解
Jan 01 Python
Python使用Shelve保存对象方法总结
Jan 28 Python
Python字符串中添加、插入特定字符的方法
Sep 10 Python
Python pandas自定义函数的使用方法示例
Nov 20 Python
python如何使用jt400.jar包代码实例
Dec 20 Python
python 连续不等式语法糖实例
Apr 15 Python
Keras自定义IOU方式
Jun 10 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
Feb 07 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中数组首字符过滤功能代码
2012/07/31 PHP
Smarty模板学习笔记之Smarty简介
2014/05/20 PHP
php实现约瑟夫问题的方法小结
2015/03/23 PHP
PHP 与 js的通信(via ajax,json)
2010/11/16 Javascript
弹出层之1:JQuery.Boxy (一) 使用介绍
2011/10/06 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
2012/10/11 Javascript
Javascript变量作用域详解
2013/12/06 Javascript
对Web开发中前端框架与前端类库的一些思考
2015/03/27 Javascript
js实现非常棒的弹出div
2016/10/06 Javascript
教大家轻松制作Bootstrap漂亮表格(table)
2016/12/13 Javascript
vuejs如何配置less
2017/04/25 Javascript
js轮播图的插件化封装详解
2017/07/17 Javascript
layui框架中layer父子页面交互的方法分析
2017/11/15 Javascript
vue.js通过路由实现经典的三栏布局实例代码
2018/07/08 Javascript
在Angular中使用JWT认证方法示例
2018/09/10 Javascript
微信上传视频文件提示(推荐)
2018/11/22 Javascript
详解Python中dict与set的使用
2015/08/10 Python
Python实现的三层BP神经网络算法示例
2018/02/07 Python
Python使用random.shuffle()打乱列表顺序的方法
2018/11/08 Python
python使用pygame框架实现推箱子游戏
2018/11/20 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法
2019/06/18 Python
python读取ini配置的类封装代码实例
2020/01/08 Python
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
canvas实现手机的手势解锁的步骤详细
2020/03/16 HTML / CSS
奥地利网上现代灯具和灯饰店:Lampenwelt.at
2018/01/29 全球购物
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
Linux内核的同步机制是什么?主要有哪几种内核锁
2016/07/11 面试题
五好党支部事迹材料
2014/02/06 职场文书
市场开发与营销专业求职信范文
2014/05/01 职场文书
应聘教师求职信
2014/07/19 职场文书
大学竞选班干部演讲稿
2014/08/21 职场文书
工程项目经理岗位职责
2015/02/02 职场文书
绵山导游词
2015/02/05 职场文书
2015年电工工作总结
2015/04/10 职场文书
萤火虫之墓观后感
2015/06/05 职场文书