Understanding Lift’s StreamingResponse

I was just looking at the Lift’s StreamingResponse and was a bit bemused by the structural type being used for the first parameter. After some fiddling around I realized that:

data: {def read(buf: Array[Byte]): Int}

This will actually make the method more flexible and not tied to a particular hierarchy of classes (and super classes). So, if your looking at Lift’s StreamingResponse and thinking “what the hell”, all you need to remember is that you can pass any thing into the first parameter as long as it implements the read method with the above signature. This, IMO, is majority cool. The default thing that implements this signature is java.io.InputStream, but you could of course pass anything - even your own custom classes!

A sample implementation might look like:

var data: Array[Byte] = // get your data here
val headers = 
    ("Content-type" -> "application/pdf") :: 
    ("Content-length" -> data.length.toString) :: 
    ("Content-disposition" -> "attachment; filname=download.pdf") 
    :: Nil
Full(StreamingResponse(
  new java.io.ByteArrayInputStream(data),
  () => {},
  data.length, 
  headers, Nil, 200)
)

</code>

So, to recap, structural types are awesome!

comments powered by Disqus