getOutputStream()



你可以會從 HttpServletResponse 取得 PrintWriter 實例,使用 println() 對瀏覽器進行字元輸出。若需要直接對瀏覽器進行位元組輸出,可以使用 HttpServletResponsegetOutputStream() 方法取得 ServletOutputStream 實例,它是 OutputStream 的子類別。

舉個例子來說,以下是個隨機產生數字圖片的 Servlet:

package cc.openhome;

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.Random;
import java.util.stream.Collectors;

import javax.imageio.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;

@WebServlet("/password")
public class Password extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("image/jpeg");

        String passwd = new Random().ints(0, 10)
                                    .limit(4)
                                    .mapToObj(String::valueOf)
                                    .collect(Collectors.joining());

        // 實際場合必須將產生的驗證碼存在某個地方,以供之後比對

        ImageIO.write(
            passwordImage(passwd), 
            "JPG", 
            response.getOutputStream()
        );
    }

    // 一些 Java 2D 的東西,作用為依傳入的數字產生圖片
    private BufferedImage passwordImage(String password) throws IOException {
        BufferedImage bufferedImage =
                 new BufferedImage(60, 20, BufferedImage.TYPE_INT_RGB);
        Graphics g = bufferedImage.getGraphics();
        g.setColor(Color.WHITE);
        g.setFont(new Font("標楷體", Font.BOLD, 16));
        g.drawString(password, 10, 15);
        return bufferedImage;
    }
}

ImageIO 類別的 write() 接受一個 OutputStream 物件,可以將你指定的 BufferedImage 寫入至指定的 OutputStream ,這邊使用 HttpServletResponsegetOutputStream() 取得的 ServletOutputStream,將圖片寫至客戶端。

瀏覽器必須知道所接收到的資料內容型態為何,這可以使用 HttpServletResponsesetContentType() 方法來設定,setContentType() 方法會自動幫你設定 content-type 回應標頭,你只要指定 MIME(Multipurpose Internet Mail Extensions)類型就可以了,要注意的是,setContentType() 方法必須在任何回應確認前執行,在回應確認後再執行 setContentType() 方法並沒有作用。。

常見的設定有 text/htmlapplication/pdfapplication/jarapplication/x-zipimage/jpeg 等。你不用強記 MIME 形式,新的 MIME 形式也不斷地在增加,必要時再使用搜尋了解一下即可。

只要引用上面 Servlet 網址就可以顯示圖片。例如寫一個表單:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <form action="pet" method="post">
            姓 名:<input type="text" name="user"><br>
            密 碼:<input type="password" name="passwd"><br>
            驗證碼:<input type="text" name="check"> <img src="password"/><br>
         <input type="submit" value="送出"/>
        </form>
    </body>
</html> 

要注意的是,同一個請求週期中,HttpServletResponsegetWriter()getOutputStream() 只能擇一使用,否則會丟出 IllegalStateException