溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

詳解Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過程

發(fā)布時(shí)間:2020-07-17 10:29:22 來源:億速云 閱讀:294 作者:小豬 欄目:開發(fā)技術(shù)

小編這次要給大家分享的是詳解Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過程,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

最近公司有個(gè)新的需求,寫了一個(gè)接口,想要把服務(wù)暴露出去,但是這個(gè)服務(wù)所在的進(jìn)程是非web項(xiàng)目,(可以理解成schedule/batch等進(jìn)程項(xiàng)目),所以沒有tomcat等容器,而且只有這一個(gè)服務(wù),無論是加dubbo服務(wù)還是加tomcat等容器都顯得復(fù)雜了。那么應(yīng)該如何將服務(wù)暴露出去?

經(jīng)過網(wǎng)上搜索后,最終解決問題,記錄在此。

為了快速搭建,使用springboot來搭建項(xiàng)目:

項(xiàng)目結(jié)構(gòu)如圖:

詳解Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過程

首先需要?jiǎng)?chuàng)建一個(gè)接口,服務(wù)的提供者和服務(wù)的調(diào)用方都依賴這個(gè)模塊。

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();

  /**
   * 根據(jù)姓名獲取年齡
   * @param name 姓名
   * @return 年齡
   */
  @NotNull
  Integer getAge(@Nullable String name);
}

然后在service模塊中,實(shí)現(xiàn)接口作為服務(wù)的提供方,需要依賴的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

實(shí)現(xiàn)接口:

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;
  }
}

暴露服務(wù):

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服務(wù)暴露出去
   */
  @Bean
  public SimpleHttpInvokerServiceExporter serviceExporter() {
    SimpleHttpInvokerServiceExporter exporter = new SimpleHttpInvokerServiceExporter();
    exporter.setService(userService);
    exporter.setServiceInterface(IUserService.class);
    return exporter;
  }

  /**
   * 為暴露的服務(wù)啟用http服務(wù)
   * @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;
  }
}

啟動(dòng)服務(wù)。

然后是服務(wù)的調(diào)用方,依賴有:

<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代理工廠調(diào)用服務(wù)
   * @return http代理工廠創(chuàng)建代理對(duì)象
   */
  @Bean
  public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
    HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean();
    factoryBean.setServiceUrl("http://localhost:9999/userService");
    factoryBean.setServiceInterface(IUserService.class);
    return factoryBean;
  }
}

使用接口,調(diào)用方法:

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;
  }
}

運(yùn)行,調(diào)用test路徑測(cè)試調(diào)用結(jié)果。

項(xiàng)目完整結(jié)構(gòu):

詳解Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過程

看完這篇關(guān)于詳解Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過程的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI