java spring根据外网IP和端口远程读取照片

本文介绍了一种使用Java获取公网IP的方法,并展示了如何通过Spring Boot配置访问服务器上的照片。此外,还提供了具体的代码实现,包括照片上传功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近上传照片的功能需要用到外网IP和端口,但是查了一圈没找到,最后在stackoverflow发现了一个方法,供参考。

获取公网IP的方法,通过使用亚马逊的网站可以获取公网IP

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class IpChecker {

    public static String getIp() throws Exception {
        URL whatismyip = new URL("http://checkip.amazonaws.com");
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(
                    whatismyip.openStream()));
            String ip = in.readLine();
            return ip;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

获取端口的方法:

import org.springframework.core.env.Environment;

@Autowired
Environment environment;
    
String port = environment.getProperty("server.port")

这里我们上传照片主要是将照片保存在服务器上,然后将公网IP+链接+相对地址保存在数据库中,前端需要照片时,通过读取数据库照片相关链接即可进行读取。之前想过将照片转成base64字符串或者byte数组进行存储,但是网上并不建议这么做,因为照片存储空间较大。因此还是考虑的将照片放在某个文件夹里,通过公网IP+链接+相对地址进行访问。下面是spring的一些配置。

当我们访问照片时,我们存储在某个文件加下面的照片可以通过file://+某个文件夹+照片名来访问。举个例子:
我们可以通过file://myfile/haha.jpg可以访问文件夹为myfile下面图片名为haha.jpg的图片。在Spring进行addResourceHandler("/img/**")配置,我们可以通过访问Spring服务器地址+/img/+haha.jpg即可访问该网址对应的服务器的文件夹(myfile)下面的图片haha.jpg

@Configuration
class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new String2LocalDateTimeConverter());
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

      registry.addResourceHandler("/img/**").addResourceLocations("file://"+System.getProperty("user.home")+"/myfile/");
       
        super.addResourceHandlers(registry);
    }
}

通过将照片上传到服务器的img文件夹下面,将链接设置为Spring的公网IP端口+/img/+图片名,即可通过链接访问。
附上传照片的代码:

    public void uploadPhoto(String id, MultipartFile file, HttpServletRequest request){
        Logger log = LoggerFactory.getLogger(this.getClass());
        if(eMapper.getE(id) == null){
            throw new ASException(NOT_EXISTS.getCode(),
                    String.format("上传照片失败", id),
                    NOT_EXISTS.getMsg());
        }

        String pathRoot = null;     
        try {
            pathRoot = "http://" + IpChecker.getIp()  //服务器地址
             + ":" + environment.getProperty("server.port");           //端口号
        } catch (Exception e) {
            e.printStackTrace();
        }
        String relativePath="";



        if (!file.isEmpty()) {
                //生成uuid作为文件名称
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                String contentType = file.getContentType();
                //获得文件后缀名称
                String imageName = contentType.substring(contentType.indexOf("/") + 1);
                String imageFullName = uuid + "." + imageName;

                relativePath =  "/myfile/" + imageFullName;
                //照片实际在服务器上存储地址
                String totalPath = System.getProperty("user.home")+relativePath;

                File dest = new File(totalPath);

                if (!dest.getParentFile().exists()) {
                    dest.getParentFile().mkdirs();
                }

                try {
                    file.transferTo(dest);
                } catch (IOException e) {
                    throw new ASException(FAILED_TO_UPLOAD.getCode(), "上传照片失败", FAILED_TO_UPLOAD.getMsg());
                }

                PDO pDO = PDO.builder()
                        .eId(equipmentId)
                        // 我们访问的照片地址
                        .pLink(pathRoot + "/img/"+imageFullName)
                        .createTime(LocalDateTime.now())
                        .build();
                ePMapper.addPLink(pDO);
            }
        request.setAttribute("pLink", pathRoot + "/img/"+imageFullName);
    }

参考文献:
Getting the ‘external’ IP address in Java
Serving Static resources from file system | Spring Boot Web

### Nacos 实际应用场景 Nacos 在微服务架构中的实际应用非常广泛,尤其是在服务发现服务配置管理方面。通过集成 Spring Cloud 生态系统,Nacos 可以为开发者提供便捷的服务治理解决方案。 #### 1. 微服务注册与发现 在一个典型的微服务体系中,各个服务实例需要相互发现并通信。Nacos 提供了一个集中式的平台来管理维护这些服务实例的信息。当一个新的服务启动时,它会自动向 Nacos 注册自己的元数据(如 IP 地址端口号等),其他依赖该服务的应用程序可以通过查询 Nacos 来获取最新的可用实例列表[^2]。 例如,在 `nacos-sentinel-example` 中展示了如何利用 Nacos 进行流量的动态调度[^1]: ```java // Application.java @SpringBootApplication @EnableDiscoveryClient public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 这段代码片段显示了如何启用服务发现功能,并让应用程序能够参与到由 Nacos 管理的服务网格之中。 #### 2. 配置中心 除了作为服务注册中心外,Nacos 同样可以充当分布式系统的统一配置管理中心。开发人员可以在 Nacos 上定义全局性的参数设置或特定于环境下的属性值,然后将其推送到运行中的各节点上。这不仅简化了部署流程,还提高了运维效率[^3]。 对于配置文件而言,只需指定 Nacos 的服务器地址即可实现远程加载配置项: ```yaml spring: cloud: nacos: server-addr: localhost:8848 # 替换成实际的Nacos服务地址 ``` 此段 YAML 文件说明了怎样连接至本地运行着的 Nacos Server 并从中读取必要的配置信息。 #### 3. API 网关集成 为了更好地支持 RESTful APIs HTTP 请求转发等功能,许多企业会选择将 Gateway 组件引入到现有的基础设施当中。借助 Spring Cloud Gateway 技术栈的优势,再加上 Nacos 所提供的强大服务能力,整个系统的灵活性得到了极大提升[^4]。 下面是一份简单的路由规则示例,用于展示如何结合两者优势创建高效的 API 接口层: ```yaml server: port: 9090 spring: application: name: gateway-service cloud: gateway: routes: - id: user_service_route uri: lb://USER-SERVICE predicates: - Path=/users/** - id: order_service_route uri: lb://ORDER-SERVICE predicates: - Path=/orders/** management: endpoints: web: exposure: include: "*" eureka: client: serviceUrl: defaultZone: http://${EUREKA_HOST}:${EUREKA_PORT}/eureka/ logging: level: org.springframework.cloud.gateway: DEBUG ``` 上述配置实现了两个不同业务领域之间的请求分发逻辑——用户模块 (`/users/**`) 订单处理部分(`/orders/**`)分别指向各自对应的服务名称。 #### 4. 跨集群调用优化 针对大型企业的复杂场景需求,有时还需要考虑多数据中心间的协同工作模式。此时就需要依靠像 Nacos 这样的工具来进行更深层次的支持,比如解决好服务级别的隔离策略以及高效的数据同步机制等问题。 在具体实践中,可能会涉及到如下操作:调整客户端 SDK 参数以适应不同的网络状况;设计合理的负载均衡算法确保资源利用率最大化等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值