[java 웹 서버] HTTP 이미지 패킷 보내기/ ByteArrayOutputStream
[java 웹 서버] HTTP 이미지 패킷 보내기/ ByteArrayOutputStream — #HTTP이미지전송 #java웹서버 #bytearrayoutputstream #개발자의도구들 AI스쿨 msa기반 java 백엔드 ...
#HTTP이미지전송 #java웹서버 #bytearrayoutputstream #개발자의도구들
AI스쿨 msa기반 java 백엔드 코스 중에 공부한 내용을 작성하였습니다
\* 현재 웹 서버 프로젝트를 진행중입니다. 전체적인 목차를 보시려면 여기에서 참고하세요
\* 전체코드: https://github.com/keyveloper/HTTP\_server.git
HTTP 응답으로 이미지 보내기
이전글을 통해 HTTP Request 패킷이 어떻게 parsing되는지에 대해 알아보았습니다. 하지만, 눈치채신 분들은 아시겠지만, parsing이후 HTTP Response를 보내는 단계에서 StringBuilder를 사용하였기 때문에, 이미지를 처리하기에는 적합하지 않았습니다. 또한 String이 아닌 많은 데이터 유형 역시 보내기가 어렵겠죠?
그래서 오늘은 어떤 데이터 유형이든지 상관없이 응답 패킷을 만들어서 보낼 수 있도록 byte\[\] 단위로 Response를처리하는 방법에 대해 알아보겠습니다.
HTTP Response 패킷 byte로 수정하기
이전에 사용한 코드
| package org.example;public class HttpResponseMaker { public static byte\[\] makePacket(Response response) { StringBuilder responseString = new StringBuilder(); // status Line responseString.append(response.getProtocol()).append(" ").append(response.getStatusCode().getCode()).append(" ") .append(response.getStatusCode().getReasonPhrase()).append("\r\n") // essential Body .append("Date: ").append(new java.util.Date()).append("\r\n"); if (response.getBody() != null){ responseString.append("Content-Type: ").append(response.getBodyType()).append("\r\n") .append("Content-Length: ").append(response.getBodyLength()).append("\r\n") .append("Connection: close\r\n") .append("\r\n"); responseString.append(response.getBody()); return responseString.toString().getBytes(); } responseString.append("Connection: close\r\n").append("\r\n"); return responseString.toString().getBytes(); }} |
|---|
이전글에서는 Reponse객체를 StringBuilder를 사용하여 HTTP 패킷을 처리하도록 하였습니다. 이는 이미지 처리에 적절하지 않은 방법입니다.
수정된 코드
| package org.example;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Locale;import java.util.TimeZone;public class HttpResponseMaker { public static byte\[\] makePacket(Response response) { SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMMM yyyy HH:mm:ss z", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { // status Line String statusLine = response.getProtocol() + " " + response.getStatusCode().getCode() + " " + response.getStatusCode().getReasonPhrase() + "\r\n"; byteArrayOutputStream.write(statusLine.getBytes()); // Essential Header String date = "Date: " + dateFormat.format(new java.util.Date()) + "\r\n"; byteArrayOutputStream.write(date.getBytes()); // optional body if (response.getBody() != null) { String contentType = "Content-Type: " + response.getBodyType() + "\r\n"; String contentLength = "Content-Length: " + response.getBody().length + "\r\n"; byteArrayOutputStream.write(contentType.getBytes()); byteArrayOutputStream.write(contentLength.getBytes()); byteArrayOutputStream.write("\r\n".getBytes()); byteArrayOutputStream.write(response.getBody()); } else { byteArrayOutputStream.write("\r\n".getBytes()); } return byteArrayOutputStream.toByteArray(); } catch (IOException e) { System.out.println("HttpResponseMaker error: " + e.getMessage()); } return null; }} |
|---|
String을 우선 형식에 맞춰 넣고, 마지막에 byte로 변환후 ByteArrayOutputStream에 넣어 반환합니다.
ByteArrayOutputStream
파이썬과 달리 자바는 배열이나 리스트를 다루는게 매우 불편하다는 생각이 듭니다. 특히나 내가 원하는 데이터만 배열로 담아내기 위해서는 Stream으로 저장후 최종 단계에서 array로 변환하는 형태를 많이 사용합니다.
이번에는 ByteArrayOutputStream을 사용하여 byte\[\]단위의 데이터를 원하는 대로 넣고, 최종적으로 byte\[\]로 변환해보았습니다.
| ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
|---|
ByteaArrayOutputStream을 우선 선언하고,
| String statusLine = response.getProtocol() + " " + response.getStatusCode().getCode() + " " + response.getStatusCode().getReasonPhrase() + "\r\n";byteArrayOutputStream.write(statusLine.getBytes()); |
|---|
원하는 만큼 String을 작성해주고, 마지막에 byte\[\]로 변환후 byteArrayOutputStream에 넣어주면 됩니다.
/image 처리하기
이미지의 경우 서버에서 어떻게 줄지는 각자 정하면됩니다. 저는 File객체를 사용해서, 이미지를 바이트로 모두 읽어들인 후 Response객체에 담아서 보내주면 됩니다. 또한 setBodyType을 "image/jpeg"으로 꼭 해줘야 웹 브라우저가 잘 테스트 할 수 있겠죠?
| private Response responseGetImage() { String imagePath = "C:\\Users\\user\\Desktop\\backEndLearn\\HTTP\_server\\img\\test.jpeg"; File file = new File(imagePath); if (!file.exists()) { return new Response(StatusCode.NOT\_FOUND); } try { byte\[\] imageBytes = Files.readAllBytes(file.toPath()); Response response = new Response(StatusCode.OK); response.setBodyType("image/jpeg"); response.setBodyLength(imageBytes.length); response.setBody(imageBytes); return response; } catch (IOException e) { throw new RuntimeException(e); }} |
|---|
postman에서 테스트하기
이제 이미지처리도 완료되었으니, 서버에서 이미지가 잘 들어오는지 테스트 해봅시다.
현재 제가 지정한 경로에 test라고 되어있는 jpeg이미지가 들어있습니다.
postman으로 확인해보니 이미지가 잘 들어오는 것을 볼 수 있습니다.
브라우저에도 GET요청이 잘되는 것을 보실 수 있습니다.



