1

有什么方法可以使用 spring web、security-oauth 堆栈生成用于下载文件的临时链接?

例如domain.com/document/ed3dk4kfjw34k43kd4k3cc,仅适用于当前会话?

4

1 回答 1

3

您可以尝试添加Map<String, String>到会话中。之后,您可以将生成的唯一字符串和文件名存储到此映射中。每次,当您需要通过唯一生成的字符串加载文件时,您都会通过字符串找到真实的文件名并将其发送给客户端。用于演示想法的简单组件:

@Component
@Scope(value = "session")
public class SessionFileMap {

    private Map<String, String> fileMap = new HashMap<>();

    public String getUniqueString(String fileName){
        for(String uniqueName: fileMap.keySet()){ 
            //check, if file already in map, return it
            if(fileMap.get(uniqueName).equals(fileName)) return uniqueName;
        }            
        //otherwise, create new
        String uniqueName = generateUniqueName();
        fileMap.put(uniqueName, fileName);
        return uniqueName;
    }

    public String getFileName(String uniqueString){
        if(fileMap.containsKey(uniqueString)){
            return fileMap.get(uniqueString);
        }
        return null;
    }

    private String generateUniqueName() {
        String uniqueString = //generation of unique string
        return uniqueString;
    }
}

当然,你必须使这个组件成为 scope session。还有很好的例子,你可以如何生成唯一的字符串。现在使用此组件的示例:

@Controller
@Scope(value = "session")
public class FileController {

    @Autowired
    private SessionFileMap fileMap;

    @Autowired
    private ApplicationContext context;

    @RequestMapping("/file")
    public String showLink(ModelMap model, HttpSession session){
        String uniqueString = fileMap.getUniqueString("/filepath/filename.ext");
        model.addAttribute("uniqueString", uniqueString);
        return "file";
    }

    @RequestMapping("/download/{uniqueString}")
    public void download(@PathVariable("uniqueString") String uniqueString,
                           HttpServletResponse response){
        String fileName = fileMap.getFileName(uniqueString);
        try{
            Resource resource = context.getResource("file:"+fileName);
            try (InputStream is = resource.getInputStream()) {

                //prepare all headers for download ...

                IOUtils.copy(is, response.getOutputStream());
                response.flushBuffer();
            }
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}

控制器必须具有范围session和组件。如果你注意到了,我曾经使用IOUtils.copy()fromorg.apache.commons来复制流,但你可以按照自己的喜好进行操作。在视图中,链接将如下所示:

<html>
<head>
    <title></title>
</head>
<body>
  <a href="/download/${uniqueString}">Download</a>
</body>
</html>

这只是基本思想的演示。所有细节都由您决定。

于 2016-03-21T10:20:38.367 回答