Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
50 changes: 21 additions & 29 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
plugins {
id 'org.springframework.boot' version '2.7.17' // 스프링 부트 플러그인 적용
id 'io.spring.dependency-management' version '1.0.15.RELEASE' // 의존성 관리 플러그인
id 'java'
id 'idea'
}

idea {
module {
inheritOutputDirs = false
outputDir = file('./webapp/WEB-INF/classes')
}
}

group 'org.example'
version '1.0-SNAPSHOT'
group = 'org.example'
version = '1.0-SNAPSHOT'
sourceCompatibility = '11' // 사용하는 자바 버전에 맞게 설정 (예: 11)

repositories {
mavenCentral()
}

ext {
springVersion = "5.1.8.RELEASE"
tomcatVersion = '8.5.42'
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testImplementation "org.springframework:spring-test:$springVersion"
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
// 1. Spring Boot Web Starter
implementation 'org.springframework.boot:spring-boot-starter-web'

// 2. Spring Boot Data JPA Starter
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

implementation("org.springframework:spring-jdbc:$springVersion")
implementation("org.springframework:spring-web:$springVersion")
implementation "org.reflections:reflections:0.10.2"
// 3. JSP 템플릿 엔진 사용을 위한 의존성
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'javax.servlet:jstl:1.2'

implementation("org.apache.commons:commons-dbcp2:2.6.0")
// 4. 데이터베이스 드라이버 (H2, MySQL 등 필요한 것 사용)
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

MySQL 커넥터 의존성 버전을 명시하세요.

MySQL 커넥터에 버전이 명시되어 있지 않습니다. Spring Boot의 의존성 관리가 처리할 수 있지만, mysql-connector-java는 deprecated되었으며 mysql-connector-j로 대체되었습니다.

다음과 같이 수정하는 것을 권장합니다:

-    runtimeOnly 'mysql:mysql-connector-java'
+    runtimeOnly 'com.mysql:mysql-connector-j'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
runtimeOnly 'mysql:mysql-connector-java'
runtimeOnly 'com.mysql:mysql-connector-j'
🤖 Prompt for AI Agents
In build.gradle around line 28, the runtimeOnly dependency uses the deprecated
artifact 'mysql:mysql-connector-java' without an explicit version; replace it
with the current artifact 'mysql:mysql-connector-j' and specify an explicit
version (or import/use the Spring Boot dependency management BOM to resolve a
compatible version) to avoid relying on deprecated coordinates and ensure
repeatable builds; update the dependency declaration to use
'mysql:mysql-connector-j:YOUR_CHOSEN_VERSION' or remove the version if you add
the Boot BOM and document which Boot version provides the connector.


runtimeOnly("com.h2database:h2:2.1.214")
runtimeOnly('mysql:mysql-connector-java:8.0.28')
// 5. Lombok (선택 사항이지만 강력히 추천)
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

implementation("org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion")
implementation("org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.2")
implementation("org.apache.tomcat.embed:tomcat-embed-jasper:$tomcatVersion")
implementation group: 'javax.servlet', name: 'jstl', version: '1.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.7.1'
// 6. Spring Boot Test Starter
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
Expand Down
991 changes: 947 additions & 44 deletions java-webMVC.ipr

Large diffs are not rendered by default.

470 changes: 306 additions & 164 deletions java-webMVC.iws

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions src/main/java/WebServerLauncher.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


import java.io.File;
import java.util.logging.Logger;

@SpringBootApplication
public class WebServerLauncher {
private static final Logger logger = Logger.getLogger(WebServerLauncher.class.getName());

public static void main(String[] args) throws Exception {
String webappDirLocation = "./webapp/";
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.getConnector();
SpringApplication.run(WebServerLauncher.class, args);

tomcat.addWebapp("", new File(webappDirLocation).getAbsolutePath());
logger.info("configuring app with basedir: " + new File(webappDirLocation).getAbsolutePath());

tomcat.start();
tomcat.getServer().await();
// String webappDirLocation = "./webapp/";
// Tomcat tomcat = new Tomcat();
// tomcat.setPort(8080);
// tomcat.getConnector();
//
// tomcat.addWebapp("", new File(webappDirLocation).getAbsolutePath());
// logger.info("configuring app with basedir: " + new File(webappDirLocation).getAbsolutePath());
//
// tomcat.start();
// tomcat.getServer().await();
}
}
68 changes: 34 additions & 34 deletions src/main/java/core/jdbc/ConnectionManager.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
package core.jdbc;

import org.apache.commons.dbcp2.BasicDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionManager {
private static final String DB_DRIVER = "org.h2.Driver";
private static final String DB_URL = "jdbc:h2:~/jwp-basic";
private static final String DB_USERNAME = "sa";
private static final String DB_PW = "";

private static BasicDataSource ds;
public static DataSource getDataSource() {
if (ds == null) {
ds = new BasicDataSource();
ds.setDriverClassName(DB_DRIVER);
ds.setUrl(DB_URL);
ds.setUsername(DB_USERNAME);
ds.setPassword(DB_PW);
}
return ds;
}

public static Connection getConnection() {
try {
return getDataSource().getConnection();
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
//package core.jdbc;
//
//import org.apache.commons.dbcp2.BasicDataSource;
//
//import javax.sql.DataSource;
//import java.sql.Connection;
//import java.sql.SQLException;
//
//public class ConnectionManager {
// private static final String DB_DRIVER = "org.h2.Driver";
// private static final String DB_URL = "jdbc:h2:~/jwp-basic";
// private static final String DB_USERNAME = "sa";
// private static final String DB_PW = "";
//
// private static BasicDataSource ds;
// public static DataSource getDataSource() {
// if (ds == null) {
// ds = new BasicDataSource();
// ds.setDriverClassName(DB_DRIVER);
// ds.setUrl(DB_URL);
// ds.setUsername(DB_USERNAME);
// ds.setPassword(DB_PW);
// }
// return ds;
// }
//
// public static Connection getConnection() { // DB의 커넥션 풀 중 커넥션 하나를 받아올 수 있음
// try {
// return getDataSource().getConnection();
// } catch (SQLException e) {
// throw new IllegalStateException(e);
// }
// }
//}
73 changes: 73 additions & 0 deletions src/main/java/core/jdbc/JdbcTemplate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//package core.jdbc;
//
//
//import java.sql.Connection;
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.sql.Statement;
//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 void update(String sql, PreparedStatementSetter pstmtSetter, KeyHolder holder) throws SQLException {
// try (Connection conn = ConnectionManager.getConnection();
// PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
//
// pstmtSetter.setParameters(pstmt);
// pstmt.executeUpdate();
//
// if (holder != null) {
// try (ResultSet rs = pstmt.getGeneratedKeys()) {
// if (rs.next()) {
// holder.setId(rs.getLong(1));
// }
// }
// }
// }
// }
//
//
// public 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 {
// T object = null;
//
// try(Connection conn = ConnectionManager.getConnection();
// PreparedStatement pstmt = conn.prepareStatement(sql);) {
// pstmtSetter.setParameters(pstmt);
//
// try (ResultSet rs = pstmt.executeQuery()) {
// if (rs.next()) {
// object = rowMapper.mapRow(rs);
// }
// }
// }
//
// return object;
// }
//
//}
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 long id;
//
// public void setId(long id) {
// this.id = id;
// }
//
// public long 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;
//}
12 changes: 12 additions & 0 deletions src/main/java/core/jdbc/RowMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//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;
//
//}
11 changes: 11 additions & 0 deletions src/main/java/jwp/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//package jwp.controller;
//
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.sql.SQLException;
//
//public interface Controller {
// String execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException;
//}
37 changes: 37 additions & 0 deletions src/main/java/jwp/controller/CreateQuestionController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package jwp.controller;


import jwp.model.Question;
import jwp.model.User;
import jwp.service.QuestionService;
import jwp.support.session.UserSessionUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

@Controller
@RequestMapping("/qna")
@RequiredArgsConstructor
public class CreateQuestionController{
private final QuestionService questionService;
@PostMapping("/create")
public String createQuestion(@RequestParam String title,
@RequestParam String contents,
HttpSession session) {
User user = UserSessionUtils.getUserFromSession(session);
if (user == null) {
return "redirect:/user/loginForm";
}
questionService.createQuestion(user.getUserId(), title, contents);
return "redirect:/";
}
}
21 changes: 21 additions & 0 deletions src/main/java/jwp/controller/CreateQuestionFormController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package jwp.controller;

import jwp.support.session.UserSessionUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/qna")
public class CreateQuestionFormController {

@GetMapping("/form")
public String showForm(HttpSession session) {
if (UserSessionUtils.isLogined(session)) {
return "qna/form.jsp";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

뷰 이름에서 .jsp 확장자를 제거하세요.

application.properties에서 이미 spring.mvc.view.suffix=.jsp로 설정되어 있으므로, 뷰 이름에 .jsp를 포함하면 최종 경로가 /qna/form.jsp.jsp가 되어 404 오류가 발생합니다.

다음과 같이 수정하세요:

-            return "qna/form.jsp";
+            return "qna/form";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return "qna/form.jsp";
return "qna/form";
🤖 Prompt for AI Agents
In src/main/java/jwp/controller/CreateQuestionFormController.java around line
17, the controller returns a view name that includes the ".jsp" extension which
causes double-suffixing; change the returned view name to omit the ".jsp" suffix
(e.g. return "qna/form") so Spring's configured view suffix is applied
correctly.

}
return "redirect:/user/loginForm";
}
}
22 changes: 22 additions & 0 deletions src/main/java/jwp/controller/CreateUserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package jwp.controller;

import jwp.model.User;
import jwp.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
@RequiredArgsConstructor
public class CreateUserController {
private final UserService userService;

@PostMapping("/signup")
public String createUser(@ModelAttribute User user) {
userService.createUser(user);
return "redirect:/user/list";
}
}
Loading