728x90
지난 포스팅 [프로젝트 셋팅]에 이어 게시글 생성에 대한 구현 방법을 정리합니다.
게시글 생성을 위해 생성할 파일들은 다음과 같습니다.
BoardDTO - BoardController - BoardService (interface) - BoardServiceImpl (구현체) - BoardMapper - View (+ JS)
* 코드는 https://github.com/wmdwjddyd6/Board-Spring-MVC 에서 확인 가능합니다.
GitHub - wmdwjddyd6/Board-Spring-MVC
Contribute to wmdwjddyd6/Board-Spring-MVC development by creating an account on GitHub.
github.com
0.A 게시판 테이블 생성
CREATE TABLE `shoppingmall`.`tb_board` (
`id` int AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`delete_yn` varchar(1) DEFAULT 'N',
`create_date` datetime DEFAULT NULL,
`views` int DEFAULT '0',
`type` varchar(20) DEFAULT 'board',
PRIMARY KEY (`id`)
)
- id (게시글 번호) : 게시글 고유 번호 (PK)
- delete_yn : 게시글 삭제 여부 (N: 삭제 안 된 상태, Y: 삭제 된 상태)
- create_date : 게시글 생성 날짜
- views : 조회수
- type : 게시글 타입 (후에 기능의 확장을 위해 넣음. 자유게시판, 비밀게시판, 공지사항 등 분리 수단)
0.B servlet-context.xml 설정
<context:component-scan base-package="com.spring.shoppingmall.controller" />
<context:component-scan base-package="com.spring.shoppingmall.service" />
- 다음 코드를 추가하여 @Component 어노테이션이 붙은 코드를 읽을 수 있도록 합니다. (@Service, @Controller 등 @Component에 포함)
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="contentType" value="text/html; charset=UTF-8"/>
</beans:bean>
<context:component-scan base-package="com.spring.shoppingmall.controller" />
<context:component-scan base-package="com.spring.shoppingmall.service" />
</beans:beans>
- servlet-context.xml 전체 코드
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.cj.jdbc.Driver"></property>
<property name="url"
value="jdbc:mysql://localhost:3306/shoppingmall?serverTimezone=Asia/Seoul">
</property>
<property name="username" value="root"></property>
<property name="password" value="asdf1234"></property>
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<mybatis-spring:scan base-package="com.spring.shoppingmall.mapper"/>
</beans>
- root-context.xml 전체 코드
- 현재는 DataBase를 위한 설정 코드가 대부분 (전 포스팅에서 설정했습니다.)
0.C View (write.jsp)
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
language="java"%>
<%@ page session="false"%>
<html>
<head>
<title>글쓰기</title>
</head>
<body>
<h1>글쓰기 화면</h1>
<form>
제목 <br />
<input size="120" type="text" id="title" name="title" /> <br /> <br />
내용 <br />
<textarea cols="100" rows="13" id="content" name="content"></textarea>
<button type="button" id="write_btn">작성</button>
</form>
<a href="/">메인으로 돌아가기</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/resources/js/write.js"></script>
</body>
</html>
- 제목과 내용을 담을 input 태그를 작성해줍니다.
- button에 이벤트를 추가하기 위해 id를 지정해줍니다.
- ajax사용을 위해 아래의 스크립트 코드를 삽입합니다.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
1. BoardDTO ( +DataBase)
@Data
@Getter
@Setter
public class BoardDTO {
private Long id;
private String title;
private String content;
private String deleteYn;
private Timestamp createDate;
private Long views;
private String type;
}
- Board테이블에 생성한 컬럼들을 변수로 선언해줍니다.
2.. BoardController
@Controller
public class BoardController {
private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
@Autowired
private BoardService boardService;
/*
* 게시글 작성 화면 이동
* */
@RequestMapping(method = RequestMethod.GET, value = "/board/write")
public String writeForm(Model model) {
return "board/write";
}
/*
* 게시글 작성
*/
@ResponseBody
@RequestMapping(method = RequestMethod.POST, value = "/board")
public int write(Model model, @RequestBody BoardDTO boardDTO) {
logger.debug("게시글 작성 호출");
int result = 0;
result = boardService.write(boardDTO);
logger.debug("result is {}", result);
return result;
}
}
- GET 요청은 게시글 작성 화면으로 이동하고, POST 요청은 게시글 등록 로직을 수행합니다.
- boardService.write()를 통해 로직을 수행합니다.
- @RequestBody로 JSON 데이터를 받아 BoardDTO객체를 생성 및 초기화합니다. (@RequestParam은 url을 통해 값을 받아오기 때문에 해당 작업에 사용하지 않음)
3. BoardService
public interface BoardService {
// 게시글 작성
int write(BoardDTO boardDTO);
}
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardMapper boardMapper;
@Override
public int write(BoardDTO boardDTO) {
boardDTO.setCreateDate(Timestamp.valueOf(LocalDateTime.now()));
boardDTO.setType("board");
return boardMapper.insertBoard(boardDTO);
}
}
- Controller에서 받은 boardDTO에 나머지 설정할 값을 setter를 통해 설정합니다.
- MyBatis를 이용하여 Mysql에 데이터를 추가하기 위해 boardMapper.insertBoard()를 호출합니다.
4. Mapper
public interface BoardMapper {
public int insertBoard(BoardDTO boardDTO);
}
- 게시글 관련 Mapper를 생성하고, 게시글 생성 쿼리를 작성할 메서드를 정의합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.shoppingmall.mapper.BoardMapper">
<sql id="boardColumns">
id
,title
,content
,delete_yn
,create_date
,views
,type
</sql>
<!--게시글 작성 -->
<insert id="insertBoard" parameterType="com.spring.shoppingmall.model.BoardDTO">
INSERT INTO
tb_board (title, content, create_date, type)
VALUES
(#{title}, #{content}, #{createDate}, #{type})
</insert>
</mapper>
- 이전 포스팅에서 생성했던 BoardMapper.xml을 수정해서 사용합니다.
- namespace랑 parameterType 등 패키지 명에 주의!
- 해당 구문이 정상 실행되면 결과값으로 1이 나오고, 실패 시 0이 나옵니다.
5. js 코드 (ajax 요청)
var writeBtn = document.getElementById("write_btn").addEventListener("click", write);
function write() {
var title = document.getElementById("title").value;
var content = document.getElementById("content").value;
var data = { "title": title, "content": content };
$.ajax({
contentType: 'application/json',
type: "POST",
url: "/board",
data: JSON.stringify(data),
success: function (response) {
console.log("성공 : " + response);
// location.href="list"; (성공 시 /board/list.jsp로 이동)
},
error: function (response) {
console.log("실패 : " + response);
console.log(response);
}
})
}
- 작성 버튼 클릭 시 이벤트를 추가하기 위해 addEventListener를 사용합니다.
- title과 content 값을 가져오고 ajax를 통해 /board/write url로 POST 요청을 보냅니다.
- 서버와 통신에 성공(요청에 대한 응답이 제대로 왔을 때)하면 success, 실패하면 error의 response로 응답 값이 들어옵니다.
- 서버의 Controller와 통신 성공 시 응답 받은 값은 1 또는 0일테니 이를 이용해서 수행할 동작을 정의 가능
- location.href를 통해 게시글 등록 성공 시 이동 할 페이지를 지정 가능합니다.
- JSON타입으로 데이터를 주고받기 위해 contentType은 json으로 맞춰주고, JSON.stringify를 사용하여 JSON 문자열로 변환하여 서버에 데이터를 전달합니다.
구현 중 겪은 에러 참고 ^-'
https://black-mint.tistory.com/74
[Spring] org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class
ajax를 이용하여 게시글 등록 구현 중 에러가 발생했습니다. 게시글 등록 요청 시 database에 입력은 잘 되지만 ajax요청의 응답으로 success구문이 실행돼야 하는데 아래의 error 부분 구문이 실행되던
black-mint.tistory.com
'Web > Spring' 카테고리의 다른 글
[Spring MVC] 4. 게시글 수정 (0) | 2022.03.31 |
---|---|
[Spring MVC] 3. 게시글 조회 (0) | 2022.03.29 |
[Spring MVC] 2. 게시글 목록 조회 (0) | 2022.03.29 |
[Spring MVC] org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class java.lang.Integer 해결 (0) | 2022.03.22 |
[Spring MVC] 0. 프로젝트 셋팅 (0) | 2022.03.08 |