Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6주차 미션 / 서버 2조 이찬양 #59

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f4a34a9
feat: servlet jsp 기본 예시 구현
lyouxsun Oct 7, 2024
33f5315
feat: jsp로 변경, HomeController 추가
lyouxsun Oct 7, 2024
bb5d666
feat: 개인정보 수정
lyouxsun Oct 7, 2024
c87f576
feat: 로그인, 로그아웃 구현
lyouxsun Oct 7, 2024
662a3b3
feat: 회원 목록 보안 강화 구현
lyouxsun Oct 7, 2024
2906265
feat: 개인정보 수정 보안 강화 구현
lyouxsun Oct 7, 2024
f200d11
feat: mvc 프레임워크 구현
lyouxsun Oct 7, 2024
6471c34
fix: 한글 인코딩 오류 수정
lyouxsun Oct 12, 2024
71712f9
fix: requestMapping으로 선언
lyouxsun Oct 12, 2024
37c008a
feat: 순수 jdbc로 userDao 클래스 구현
lyouxsun Oct 24, 2024
3f23dbe
refactor: jdbcTemplate 구현
lyouxsun Oct 24, 2024
0f60e28
refactor: try-with-resource, generic 적용
lyouxsun Oct 24, 2024
7fe01ab
refactor(controller): MemoryUserRepository에서 UserDao로 변경
lyouxsun Oct 28, 2024
a5f5cd2
refactor(db): 미사용 MemoryUserRepository 제거
lyouxsun Oct 28, 2024
0f567e6
feat(Question): Question 엔티티 생성
lyouxsun Oct 28, 2024
b99d53f
feat(QuestionDao): QuestionDao 구현
lyouxsun Oct 28, 2024
6bdf143
feat: 홈화면에서 질문 목록 조회
lyouxsun Oct 28, 2024
6da08b6
feat: 회원만 질문 가능하도록 구현
lyouxsun Oct 28, 2024
e92d397
feat: 질문 생성 및 저장 구현
lyouxsun Oct 28, 2024
a6fd9c7
feat(ShowQuestionController): 질문 조회 기능 구현
lyouxsun Oct 29, 2024
920d11d
feat(UpdateQuestionController): 질문 수정 기능 구현
lyouxsun Oct 29, 2024
65a94b6
feat(Answer): Answer 엔티티 생성
lyouxsun Oct 29, 2024
8cad687
feat(AnswerDao): AnswerDao 구현
lyouxsun Oct 30, 2024
cabe08f
feat(ShowQuestionController): 답변 조회 기능 구현
lyouxsun Oct 30, 2024
9c4b088
feat(CreateAnswerController): 답변 생성 기능 구현
lyouxsun Oct 30, 2024
295d2a0
chore(controller): 폴더 구조 변경
lyouxsun Oct 30, 2024
0f45f54
refactor: View 적용
lyouxsun Nov 1, 2024
bf928f3
refactor: ForwardController에 View 적용
lyouxsun Nov 1, 2024
29f5bd0
fix: DispatcherServlet 수정
lyouxsun Nov 1, 2024
330b392
feat: add ModelAndView and refactoring
cyLee1111 Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .run/WebServerLauncher.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="WebServerLauncher" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="WebServerLauncher" />
<module name="java-webMVC.main" />
<option name="VM_PARAMETERS" value="-Dfile.encoding=UTF-8" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
41 changes: 0 additions & 41 deletions src/main/java/core/db/MemoryUserRepository.java

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/java/core/db/Repository.java

This file was deleted.

86 changes: 86 additions & 0 deletions src/main/java/core/jdbc/JdbcTemplate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package core.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class JdbcTemplate<T> {

public void update(String sql, PreparedStatementSetter pstmtSetter) throws SQLException {
try (Connection conn = ConnectionManager.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmtSetter.setParameters(pstmt);
pstmt.executeUpdate();
}
}

public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws SQLException {
List<T> objects = new ArrayList<>();

try (Connection conn = ConnectionManager.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();) {
while (rs.next()) {
T object = rowMapper.mapRow(rs);
objects.add(object);
}
}
return objects;
}

public T queryForObject(String sql, PreparedStatementSetter pstmtSetter, RowMapper<T> rowMapper) throws SQLException {
ResultSet rs = null;
T object = null;

try (Connection conn = ConnectionManager.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);) {
pstmtSetter.setParameters(pstmt);
rs = pstmt.executeQuery();
if (rs.next()) {
object = rowMapper.mapRow(rs);
}
} finally {
if (rs != null)
rs.close();
}
return object;
}

public void update(String sql, PreparedStatementSetter pstmtSetter, KeyHolder keyHolder) throws SQLException {
ResultSet rs = null;
try (Connection conn = ConnectionManager.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS)) {
pstmtSetter.setParameters(pstmt);
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
keyHolder.setId((int) rs.getLong(1));
}
} finally {
if (rs != null)
rs.close();
}
}

public List<T> query(String sql, PreparedStatementSetter pstmtSetter, RowMapper<T> rowMapper) throws SQLException {
List<T> objects = new ArrayList<>();
ResultSet rs = null;

try (Connection conn = ConnectionManager.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);) {
pstmtSetter.setParameters(pstmt);
rs = pstmt.executeQuery();
while (rs.next()) {
T object = rowMapper.mapRow(rs);
objects.add(object);
}
} finally {
if (rs != null)
rs.close();
}
return objects;
}
}
13 changes: 13 additions & 0 deletions src/main/java/core/jdbc/KeyHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.jdbc;

public class KeyHolder {
private int id;

public void setId(int id) {
this.id = id;
}

public int getId() {
return id;
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/jdbc/PreparedStatementSetter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core.jdbc;

import java.sql.PreparedStatement;
import java.sql.SQLException;

@FunctionalInterface
public interface PreparedStatementSetter {
void setParameters(PreparedStatement ps) throws SQLException;
}
11 changes: 11 additions & 0 deletions src/main/java/core/jdbc/RowMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core.jdbc;

import jwp.model.User;

import java.sql.ResultSet;
import java.sql.SQLException;

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(ResultSet rs) throws SQLException;
}
20 changes: 20 additions & 0 deletions src/main/java/core/mvc/AbstractController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package core.mvc;

import core.mvc.view.JsonView;
import core.mvc.view.JspView;
import core.mvc.view.ModelAndView;

import java.util.Map;

public abstract class AbstractController implements Controller {
protected ModelAndView jspView(String viewName) {
return new ModelAndView(new JspView(viewName));
}
protected ModelAndView jsonView() {
return new ModelAndView(new JsonView());
}
}




11 changes: 11 additions & 0 deletions src/main/java/core/mvc/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core.mvc;

import core.mvc.view.ModelAndView;
import core.mvc.view.View;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Controller {
ModelAndView execute(HttpServletRequest req, HttpServletResponse resp) throws Exception;
}
36 changes: 36 additions & 0 deletions src/main/java/core/mvc/DispatcherServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package core.mvc;

import core.mvc.view.ModelAndView;
import core.mvc.view.View;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "dispatcher", urlPatterns = "/", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {
private RequestMapping requestMapping;
private static final String REDIRECT_PREFIX = "redirect:";

@Override
public void init() {
requestMapping = new RequestMapping();
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
String url = req.getRequestURI();
Controller controller = requestMapping.getController(url);
try {
ModelAndView mav = controller.execute(req, resp);
mav.render(req, resp);
} catch (Exception e) {
System.out.println(e.getMessage());
throw new ServletException(e.getMessage());
}
}
}
25 changes: 25 additions & 0 deletions src/main/java/core/mvc/ForwardController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package core.mvc;

import core.mvc.view.JspView;
import core.mvc.view.ModelAndView;
import core.mvc.view.View;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ForwardController implements Controller {

private final String forwardUrl;

public ForwardController(String forwardUrl) {
this.forwardUrl = forwardUrl;
if (forwardUrl == null) {
throw new NullPointerException("forwardUrl is null");
}
}

@Override
public ModelAndView execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
return new ModelAndView(new JspView(forwardUrl));
}
}
40 changes: 40 additions & 0 deletions src/main/java/core/mvc/RequestMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package core.mvc;

import jwp.controller.*;
import jwp.controller.qna.*;
import jwp.controller.user.*;

import java.util.HashMap;
import java.util.Map;

public class RequestMapping {

private static final Map<String, Controller> controllers = new HashMap<>();

static {
controllers.put("/", new HomeController());
controllers.put("/user/signup", new CreateUserController());
controllers.put("/user/list", new ListUserController());
controllers.put("/user/login", new LoginController());
controllers.put("/user/logout", new LogoutController());
controllers.put("/user/update", new UpdateUserController());
controllers.put("/user/updateForm", new UpdateUserFormController());

controllers.put("/user/form", new ForwardController("/user/form.jsp"));
controllers.put("/user/loginForm", new ForwardController("/user/login.jsp"));
controllers.put("/user/loginFailed", new ForwardController("/user/loginFailed.jsp"));

controllers.put("/qna/form", new CreateQuestionFormController());
controllers.put("/qna/updateForm", new UpdateQuestionFormController());
controllers.put("/qna/update", new UpdateQuestionController());
controllers.put("/qna/create", new CreateQuestionController());
controllers.put("/qna/show", new ShowQnaController());

controllers.put("/api/qna/addAnswer", new CreateAnswerController());
}


public Controller getController(String url) {
return controllers.get(url);
}
}
33 changes: 33 additions & 0 deletions src/main/java/core/mvc/view/JsonView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package core.mvc.view;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class JsonView implements View{
@Override
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();

// model -> JSON
out.print(objectMapper.writeValueAsString(model));
}

private static Map<String, Object> createModel(HttpServletRequest request) {
Enumeration<String> names = request.getParameterNames();
Map<String, Object> model = new HashMap<>();
while (names.hasMoreElements()) {
String name = names.nextElement();
model.put(name, request.getParameter(name));
}
return model;
}

}
33 changes: 33 additions & 0 deletions src/main/java/core/mvc/view/JspView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package core.mvc.view;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class JspView implements View {

private final String viewName;
private static final String REDIRECT_PREFIX = "redirect:";


public JspView(String viewName) {
this.viewName = viewName;
}

@Override
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (viewName.startsWith(REDIRECT_PREFIX)) {
response.sendRedirect(viewName.substring(REDIRECT_PREFIX.length()));
return;
}

// request에 model 저장
for (Map.Entry<String, Object> entry : model.entrySet()) {
request.setAttribute(entry.getKey(), entry.getValue());
}

RequestDispatcher rd = request.getRequestDispatcher(viewName);
rd.forward(request, response);
}
}
Loading