用Java将文件块转换为页面

时间:2016-09-10 20:47:43

标签: java json spring file spring-mvc

我有一个代码,我以块的形式读取一个大文件并将其转换为JSON以将其发送到Spring MVC控制器,我的方法看起来像这样,我传递到我想要在偏移量和chunkSize中启动noBytes,结果传递给JSON并发送到我的控制器

  public String readByteBlock(File file, int offset, int noBytes) throws IOException {
    InputStream in = new FileInputStream(file);
    byte[] result = new byte[noBytes];
    in.skip(offset);
    in.read(result, 0, noBytes);
    return FileSaver.byteArrayToString(result, noBytes);
}

我有问题让我的控制器中的下一个和之前的分页工作

@RequestMapping("/page/{id}")
@ResponseBody   
    File file = new File("C:/teste.txt");
    FileSaver fs = new FileSaver();
    int byteblock = 100;        
    int offset = 0;
    if(id.equals("next")){      
        offset = (int) req.getSession().getAttribute("prevEndPos"); 
        String s = fs.readByteBlock(file, offset, byteblock);       
        req.getSession().setAttribute("prevStartPos", offset);     
        req.getSession().setAttribute("prevEndPos", (offset + byteblock) );       
        return s;
    }
    if(id.equals("prev")){
        offset = (int) req.getSession().getAttribute("prevStartPos") - byteblock ; 
        if(offset < 0 ){
            String s = fs.readByteBlock(file, 0, byteblock);
              return s;
        }
        String s = fs.readByteBlock(file, offset, byteblock);         
        req.getSession().setAttribute("prevStartPos", (offset - byteblock) );      
        return s;
    }
    String s = fs.readByteBlock(file, 0, byteblock);
    req.getSession().setAttribute("prevStartPos", offset);
    req.getSession().setAttribute("prevEndPos", (offset + byteblock));
    return s;

因此,文件的每个块都将被放入我的应用程序的html表中,我将当前块startByte和endByte保存到我的会话中但是当用户按下我页面上的上一个按钮时,我怎么知道前一个块的位置开始和结束?因为会话将保持当前页面而不是前一页

2 个答案:

答案 0 :(得分:2)

首先讲一下关于分页的一般情况。 简单分页只有两个属性:

  1. 页面尺寸
  2. 页码
  3. 后端将发回数据和以下元数据:

    1. 总页数
    2. 当前页码
    3. 当前页面尺寸
    4. 然后客户端负责询问所需的数据块,通过发送页码和页面大小,后端将计算偏移量并结束。唯一需要注意的是,如果用户增加页面大小,那么总页数(客户端在前一次调用中收到的)不再有效,但在这种情况下,服务器只返回没有数据,新的元数据。 许多框架都使用这种方法,例如后端的Spring Data和前端的EXT JS。

      由于您使用的是Spring,因此您应该创建一个同时包含数据和元数据的DTO类:

      Class PageResult {
          String data;
          int totalPageCount;
          int currentPage;
          int pageSize;       
      }
      

      在使用String传输数据时,请注意您可能必须在前端调用JSON.parse(),并且您的JSON将被字符串转义,看起来很傻;如果您使用Jacksons ObjectMapper读取数据,我建议使用返回JsonNode的ObjectMapper.readTree(),并将其放入DTO类。

      在前端,您可以使用建议的页面大小和页码的输入框进行下拉菜单。如果您想要下一个和上一个,只需发送当前页面+/- 1的请求和页面大小,那么后端将计算开始页面,结束页面和总页面。

答案 1 :(得分:-1)

为什么不添加两个包含适当值的int数组,而不是在会话中添加两个int属性?还要添加一个&#39;页面&#39;属性,所以你可以做类似

的事情
if(id.equals("prev") {
    List<Integer> offsetStarts = req.getSession.getAttribute("offsetStarts);
    List<Integer> offsetEnds = req.getSession.getAttribute("offsetEnds);
    int lastPage = req.getSession.getAttribute("page");
    int desiredPage = lastPage -1;
    int offsetStart = offsetStarts.get(desiredPage);
    int offsetEnd = offsetEnd.get(desiredPage);
    // get the chunk as desired, and return it
    req.getSession().setAttribute("page", desiredPage);
}
// if it's a new chunk, append offsets to the arrays