zoukankan      html  css  js  c++  java
  • 基于spring http服务远程调用

    最近公司有个新的需求,写了一个接口,想要把服务暴露出去,但是这个服务所在的进程是非web项目,(可以理解成schedule/batch等进程项目),所以没有tomcat等容器,而且只有这一个服务,无论是加dubbo服务还是加tomcat等容器都显得复杂了。那么应该如何将服务暴露出去?

    经过网上搜索后,最终解决问题,记录在此。

    为了快速搭建,使用springboot来搭建项目:

    项目结构如图:

     首先需要创建一个接口,服务的提供者和服务的调用方都依赖这个模块。

    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>
    View Code

    配置文件需要加上:

    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>
    View Code

    配置文件:

    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路径测试调用结果。

    项目完整结构:

  • 相关阅读:
    PAIP.img ROM文件提取APK
    paip.提升程序稳定性最佳实践
    paip.验证码识别序列号的反转
    paip.android APK安装方法大总结系统应用的安装
    paip.php调试脱离IDE VC59
    paip.声音按键音延迟的解决
    paip.提升效率几款任务栏软件vc59
    paip.android 读取docx总结
    paip.C#.NET多线程访问 toolStripStatusLabel VC421
    paip.Image对象出现“对象当前正在其他地方使用或者GDI+中发生一般性错误的解决
  • 原文地址:https://www.cnblogs.com/Zs-book1/p/13067277.html
Copyright © 2011-2022 走看看