Home > OS >  How does spring boot return byte stream in real time like PHP's readfile function?
How does spring boot return byte stream in real time like PHP's readfile function?

Time:12-17

I am solving a requirement. I am using the springboot framework. Now there is an interface that passes in the parameter url. This url is a network file address. After receiving the request, the interface uses its own network to request the network file and returns it to the client in real time. , php's readfile function can solve the problem, but is there such a solution in the java language? What I need is to return to the client in real time, instead of reading all and returning to the client

@Controller
@Api(tags = "test")
@RequestMapping("/test")
@CrossOrigin
public class TestController {

    @RequestMapping(value = "/get", method = RequestMethod.POST)
    @ApiOperation(value = "get")
    public ResponseEntity<FileSystemResource> test() throws IOException {
      
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "{\"123\": 1}");
        Request request = new Request.Builder()
                .url("https://github.com/xujimu/ios_super_sign/archive/refs/heads/master.zip")
                .method("GET", body)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        
    }


}

CodePudding user response:

You can use ResponseEntity<StreamingResponseBody> for this.

You have choose which content-type you want to return. We ended up with produces = MediaType.APPLICATION_NDJSON_VALUE.

We had to modify the way we did rest request by changing from RestClient to WebClient`:

Flux<DataBuffer> dataStream = return webClient.method(method)
                .uri(url)
                .retrieve()
                .bodyToFlux(DataBuffer.class);

DataBufferUtils.write(dataStream, response.getOutputStream())
                .map(DataBufferUtils::release)
                .blockLast();

When we finally got this to work, it works really well :)

You can see some other examples on https://www.baeldung.com/spring-mvc-sse-streams.

CodePudding user response:

I solved the problem by java's URL class

package com.api.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.api.common.result.PageReq;
import com.api.common.result.PageResult;
import com.api.common.result.Result;
import com.api.common.user.AddBalanceReq;
import com.api.constant.ResultCode;
import com.api.dao.ApiUserDao;
import com.api.dao.UserFlowDao;
import com.api.entity.ApiUserEntity;
import com.api.entity.UserFlowEntity;
import com.api.execption.ResRunException;
import com.api.service.ApiUserService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import reactor.core.publisher.Flux;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.DataBuffer;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;


@Controller
@Api(tags = "test")
@RequestMapping("/test")
@CrossOrigin
public class TestController {
 
    /**
     * 添加用户月
     *
     * @param req
     * @return
     */
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    @ApiOperation(value = "get")
    public void test(String url, HttpServletResponse response) throws IOException {

        URL url1 = new URL(url);

        InputStream is = url1.openStream();

        int ch;
        while ((ch = is.read()) != -1) {
            response.getWriter().write(ch);
        }
        
    }


}

  • Related