응답 데이터를 처리하는 로직을 HttpResponse 클래스로 분리
- 아래 코드를 보면 응답 데이터 처리를 위한 많은 중복이 있다. 중복을 제거하자.
private void response302LoginSuccessHeader(DataOutputStream dos) {
try {
dos.writeBytes("HTTP/1.1 302 Found \r\n");
dos.writeBytes("Content-Type: text/html;charset=utf-8 \r\n");
dos.writeBytes("Set-Cookie: logined=true \r\n");
dos.writeBytes("Location: /index.html \r\n" );
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void response200HeaderWithCss(DataOutputStream dos, int lengthOfBodyContent) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
dos.writeBytes("Content-Type: text/css,*/*;q=0.1\r\n");
dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void response200HeaderWithScript(DataOutputStream dos, int lengthOfBodyContent) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
dos.writeBytes("Content-Type: application/javascript\r\n");
dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void response200Header(DataOutputStream dos, int lengthOfBodyContent) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n");
dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n");
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
제거하려면?
- 응답 헤더 정보를 Map<String, String>으로 관리한다.
private Map<String, String> header = new HashMap<>();
- 응답을 보낼때 HTML, CSS, JS 파일을 직접 읽어 응답으로 보내는 메서드는 forward(), 요청한 URL이 아닌 전달받은 URL로 리다이렉트하는 메서드는 sendRedirect()로 구현한다.
public class HttpResponse {
private static final Logger log = LoggerFactory.getLogger(HttpResponse.class);
private Map<String, String> headers = new HashMap<>();
DataOutputStream dos = null;
public HttpResponse(OutputStream out) {
dos = new DataOutputStream(out);
}
public void addHeader(String key, String value) {
headers.put(key, value);
}
public void forward(String url) {
try {
byte[] body = Files.readAllBytes(Paths.get("./webapp" + url));
if( url.endsWith(".css") ) {
headers.put("Content-Type", "text/css,*/*;q=0.1");
} else if ( url.endsWith(".js") ) {
headers.put("Content-Type", "application/javascript");
} else {
headers.put("Content-Type", "text/html;charset=utf-8");
}
headers.put("Content-Length", body.length + "");
response200Header(dos);
responseBody(dos, body);
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendRedirect( String redirectUrl ) {
try {
dos.writeBytes("HTTP/1.1 302 Found \r\n");
processHeader();
dos.writeBytes("Location: " + redirectUrl + " \r\n" );
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void processHeader() {
Set<String> keySet = headers.keySet();
for (String key : keySet) {
try {
dos.writeBytes(key + ": " + headers.get(key) + " \r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void response200Header(DataOutputStream dos) {
try {
dos.writeBytes("HTTP/1.1 200 OK \r\n");
processHeader();
dos.writeBytes("\r\n");
} catch (IOException e) {
log.error(e.getMessage());
}
}
private void responseBody(DataOutputStream dos, byte[] body) {
try {
dos.write(body, 0, body.length);
dos.flush();
} catch (IOException e) {
log.error(e.getMessage());
}
}
public void forwardBody(String body) {
byte[] contents = body.getBytes();
headers.put("Content-Type", "text/html;charset=utf-8");
headers.put("Content-Length", contents.length +"");
response200Header(dos);
responseBody(dos, contents);
}
}
'Java' 카테고리의 다른 글
[Java] 세션(HttpSession) 구현 / 세션은 HTTP 쿠키를 기반으로 동작 (0) | 2023.03.21 |
---|---|
[Java] 다형성을 활용해 클라이언트 요청 URL에 대한 분기 처리를 제거 (0) | 2023.03.20 |
[Java] 요청 데이터 처리 로직을 HttpRequest 클래스로 분리 및 리팩토링 (0) | 2023.03.19 |
[Java] HTTP 웹 서버 구현 / CSS 지원하기 (0) | 2023.03.17 |
[Java] HTTP 웹 서버 구현 / 로그인 구현 (0) | 2023.03.17 |
댓글