如何在一个Controller里,讲请求forward到另外一个url?

我有一个服务器A,运行JFinal的系统,此时 A服务器的后面还有其他服务器如B,但是在A后面, 客户端浏览器无法直接访问B的 /downfile 服务地址。 我想在A服务器上写一个方法   /downloadB ,能不能实现forward的功能?


我利用sendRedirect是不通的,浏览器进行了跳转,无法下载B的文件

getResponse().setHeader("content-disposition", "attachment;filename=B.log");
getResponse().sendRedirect("


最后还是自己动手,丰衣足食把, 自己写了一个StreamRender,把B的 inputstream流 直接导向到 当前response的 outputstream里面,就实现代理的功能,
这个与FileRender类似,但FileRender是针对已经存在的文件。

不废话了,献上代码

package cn.ct.ums.common;

import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.InputStream;
import java.io.OutputStream;

public class StreamRender extends Render {
    private String url;
    private String filename="downloadfile";
    public StreamRender(String url) {
        this.url = url;
    }
    public StreamRender(String url,String fn) {
        this.url = url;
        this.filename = fn;
    }
    public void setFilename(String fn){
        this.filename = fn;
    }

    @Override
    public void render() {
        response.setHeader("Content-disposition", "attachment; filename=" + filename);
        response.setContentType("application/octet-stream");
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet get =new HttpGet(url);
        InputStream input = null;

        try {
            HttpResponse httpResponse = httpClient.execute(get);
            int i = httpResponse.getStatusLine().getStatusCode();
            if(i==200){
                input = httpResponse.getEntity().getContent();
                OutputStream outputStream = response.getOutputStream();
                byte[] buffer = new byte[1024];
                int length;
                while ((length = input.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, length);
                }
                outputStream.flush();
                outputStream.close();
            }else{
                throw new RenderException("DownloadFail");
            }
        } catch (Exception e) {
            throw new RenderException(e);
        } finally {
            if (input != null) {
                try {input.close();
                } catch (Exception e) {}
            }
        }
    }
}


评论区

JFinal

2020-10-28 22:04

forward 是指应用程序之内的动作,你想要的动作应该是 redirect

但是你可能不希望客户直接访问 B 的 /downfile,一般要使用代理,也就是服务器 A 作为中转,与服务器 B 交互,将数据再转递给客户端,这个模式比较麻烦

我建议使用 jfinal 社区视频文件下载的方案,在这里有介绍:
https://jfinal.com/app/3

zgysc

2020-10-29 11:48

感谢波总回复,我单独写了一个StreamRender继承Render来模拟反向代理的功能,把不能直接访问的网络资源inputstream直接流到 response里的outputstream里,实现下载

JFinal

2020-10-29 12:29

@zgysc 扩展 Render 实现代理也是很方便的,记得在分享频道分享出来啊

zgysc

2020-10-29 15:02

@JFinal 好的波总,代码已经分享, 另外还有一个关于getPara(int index)的问题,不知道是不是bug, 默认情况下 /v0-v1-v2 可以用getPara(1) 正常获取到v1,但我在DemoConfig类里面的public void configConstant(Constants me)方法中,修改默认分隔符 me.setUrlParaSeparator("##"); 之后 /v0##v1##v2 就不能获取到v1或者v2了

JFinal

2020-10-29 16:19

@zgysc 分享的代码量很少,很赞

setUrlParaSeparator 不能使用字符 '#',因为这个字符在 url 中有别的用途,在 url 中叫做锚

热门分享

扫码入社