일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 플러터
- 수제비2022 정리
- 스프링 MVC
- pem키 분실
- FLUTTER
- 레이튼 교수와 이상한 마을
- N-Queen
- 확진
- 2022 정보처리기사
- 수제비 2022
- 얘들아 잘 지내니
- 정보처리기사2022
- 생일축하해 나 자신
- 지독한 컨셉충
- 다들 안잊어서
- 모바일 청첩장
- 대외활동
- 대학생
- 자가격리
- 아싸의 생일
- 교수님 과제 이제 그만..
- CRUDS
- AWS
- 교육봉사
- 다음에 또 만나자
- 정보처리기사 2022
- 뽀모도로 타이머
- 다행이야...ㅎ
- 개강해짐
- 재택치료
- Today
- Total
Rei’s Tech diary
[Spring] 모바일웹 청첩장 프로젝트 본문
소개
요즘, 결혼한다면 꼭 만들어야 하는 모바일 청첩장.
셀프로 만드는 사이트도 많지만 잘림이나 이미지 크기, 깨짐 이슈로 퀄리티가 별로라는 글을 여럿 봤었다.
실제로 최근 언니 친구가 결혼한다고 모바일 청첩장을 보게 됐는데 사진이 깨지고...글자도 엉망이고.. 불편했었다.
그래서 인터페이스를 좀 더 깔끔하게 구성하고, 게시판 기능을 추가하여 하객들이 축하글을 남길 수 있는 공간을 마련해 보았다.
추가로 신랑 측, 신부 측 따로 볼 수 있게 Search 기능도 넣어보았다.
2주 정도...? 걸렸으니, 본인이 결혼한다면 셀프로 만들어보는 것도 추천.
블록 다이어그램
Annotation 기반 스프링 MVC 구조를 이용하여, MySQL에 저장된 데이터들을 이용, CRUDS 기능을 제공할 예정이다.
[Annotation 설정]
<context:component-scan base-package="com.spring.*"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/views/boardViews/"/>
<property name="suffix" value=".jsp"/>
</bean>
[web.xml 설정]
<servlet-mapping>
<servlet-name>action-Servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>action-Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/project.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
DB 설계
seq(PK) : 구분
title : 글 제목
part : 신랑측, 신부측 하객 구분 (group으로 하면 sql 문법 오류남)
writer : 글쓴이
content : 내용
regdate : 작성 날짜
[DB 연결 부분]
package com.spring.boardex.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcUtil {
static String id="본인 DB 아이디";
static String password = "본인 DB 비밀번호";
static String url = "본인 DB url";
static Connection conn=null;
static PreparedStatement pstmt=null;
static ResultSet rs = null;
public static Connection getConnection() {
try {
//jdbc 드라이버 로딩
Class.forName("com.mysql.jdbc.Driver");
//디비에 연결
conn = DriverManager.getConnection(url, id, password);
System.out.println("MySQL 디비 연결 완료 ");
return conn;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void closeConnection(Connection conn,
PreparedStatement pstmt, ResultSet rs) {
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
DO, DAO 설정
# DO
import java.sql.Timestamp;
public class projectDo {
private int seq;
private String title;
private String group;
private String writer;
private String content;
private Timestamp regdate;
@Override
public String toString() {
return "projectDo [seq=" + seq +
", title=" + title +
", part=" + group +
", writer=" + writer +
", content=" + content +
", regdate=" + regdate +"]";
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Timestamp getRegdate() {
return regdate;
}
public void setRegdate(Timestamp regdate) {
this.regdate = regdate;
}
}
#DAO
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.spring.boardex.common.JdbcUtil;
@Repository("projectDaoSpring")
public class projectDao {
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
@Autowired
JdbcTemplate jdbcTemplate;
public void insertBoard(projectDo pdo) {
System.out.println("insertBoard()(Spring JDBC) => Start !!");
String sql = "insert into wedding (title, part, writer, content) "
+ "values (?,?,?,?)";
jdbcTemplate.update(sql, pdo.getTitle(), pdo.getGroup(), pdo.getWriter(), pdo.getContent());
System.out.println("insertBoard()(Spring JDBC) => End !!");
}
public projectDo getBoard(projectDo pdo) {
System.out.println("getBoard()(Spring JDBC) ==> ");
String sql = "select * from wedding where seq=?";
Object[] args = {pdo.getSeq()};
return jdbcTemplate.queryForObject(sql, args, new BoardRowMapper());
}
public ArrayList<projectDo> getBoardList(){
System.out.println("getBoardList()(Spring JDBC) ==> ");
String sql = "select * from wedding";
Object[] args = {};
return (ArrayList<projectDo>) jdbcTemplate.query(sql, args, new BoardRowMapper());
}
public void updateBoard(projectDo pdo) {
System.out.println("updateBoard()(Spring JDBC) ==> ");
String sql = "update wedding set title=?, content=? where seq=?";
jdbcTemplate.update(sql, pdo.getTitle(), pdo.getContent(), pdo.getSeq());
}
public void deleteBoard(projectDo pdo) {
System.out.println("deleteBoard()(Spring JDBC) ==> ");
//DB 연결
String sql = "delete from wedding where seq=?";
jdbcTemplate.update(sql,pdo.getSeq());
}
//6장 19p
public ArrayList<projectDo> searchBoardList(String searchCon, String searchKey) {
System.out.println("searchBoardList()(Spring JDBC) ==> ");
String sql="";
if(searchCon.equals("writer")) {
sql = "select * from wedding where writer=? order by seq desc;";
}
else if(searchCon.equals("part")) {
sql = "select * from wedding where part=? order by seq desc;";
}
Object [] args = {searchKey};
return (ArrayList<projectDo>) jdbcTemplate.query(sql, args, new BoardRowMapper());
}
}
class BoardRowMapper implements RowMapper<projectDo>{
@Override
public projectDo mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("mapRow()(Spring JDBC 처리)==> ");
projectDo pdo = new projectDo();
pdo.setSeq(rs.getInt(1));
pdo.setTitle(rs.getString(2));
pdo.setGroup(rs.getString(3));
pdo.setWriter(rs.getString(4));
pdo.setContent(rs.getString(5));
pdo.setRegdate(rs.getTimestamp(6));
return pdo;
}
}
Controller
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.spring.boardex.impl.projectDao;
import com.spring.boardex.impl.projectDo;
@Controller
public class BoardControllerSpring {
@Autowired
projectDao projectDaoSpring;
@RequestMapping(value="/insertBoard.do")
public String insertBoard() {
System.out.println("insertBoard() ==> ");
//뷰어 호출
return "insertBoardView";
}
@RequestMapping(value="/insertProcBoard.do")
public String insertProcBoard(projectDo pdo) {
System.out.println("insertProcBoard()(Spring JDBC) ==> ");
System.out.println("title : " + pdo.getTitle());
System.out.println("group : " + pdo.getGroup());
System.out.println("writer : " + pdo.getWriter());
System.out.println("content : " + pdo.getContent());
System.out.println("regdate : " + pdo.getRegdate());
projectDaoSpring.insertBoard(pdo);
return "redirect:getBoardList.do";
}
@RequestMapping(value="/getBoard.do")
public String getBoard(projectDo pdo, Model model) {
System.out.println("GetBoardController()(Spring JDBC) ==> ");
//DO에 seq 값이 제대로 설정되어있는지 확인만 함
System.out.println("seq : " + pdo.getSeq());
projectDo board = projectDaoSpring.getBoard(pdo);
model.addAttribute("board", board);
//해당 매칭 값이 ModelAndView이기에
return "getBoardView";
}
@RequestMapping(value="/getBoardList.do")
public String getBoardList(projectDo pdo, Model model) {
System.out.println("getBoardList()(Spring JDBC) ==> ");
ArrayList<projectDo> blist = projectDaoSpring.getBoardList();
System.out.println(blist);
model.addAttribute("bList", blist);
return "getBoardListView";
}
@RequestMapping(value="/modifyBoard.do")
public String modifyBoard(projectDo pdo, Model model) {
System.out.println("ModifyBoardController()(Spring JDBC) ==> ");
System.out.println("seq : " + pdo.getSeq());
projectDo board = projectDaoSpring.getBoard(pdo);
model.addAttribute("board", board);
return "getModifyView";
}
@RequestMapping(value="/modifyProcBoard.do")
public String modifyProcBoard(projectDo pdo, Model model) {
System.out.println("ModifyProcBoardController()(Spring JDBC) ==> ");
projectDaoSpring.updateBoard(pdo);
return "redirect:getBoardList.do";
}
@RequestMapping(value="/deleteBoard.do")
public String deleteBoard(projectDo pdo, Model model) {
System.out.println("DeleteBoardController()(Spring JDBC) ==>");
projectDaoSpring.deleteBoard(pdo);
return "redirect:getBoardList.do";
}
// 6장 16p
@RequestMapping(value="/searchBoardList.do")
public String searchBoardList(
@RequestParam(value="searchCon") String searchCon,
@RequestParam(value="searchKey") String searchKey,
Model model) {
System.out.println("searchBoardList.do ==> ");
System.out.println("searchCon : " + searchCon);
System.out.println("searchKey: " + searchKey);
ArrayList<projectDo> bList = projectDaoSpring.searchBoardList(searchCon, searchKey);
model.addAttribute("bList", bList);
return "getBoardListView";
}
}
VIEW
html+css, javascript로 프론트엔드 만들었는데, 지저분하니 파일로 첨부..
getBoardList.view : 메인 뷰
getBoardView : 축하글 뷰
getModifyView : 글 수정 뷰
insertBoardView : 글 작성 뷰
카카오 맵 api - 웨딩홀 위치를 나타낼 예정
<!-- 카카오 맵 api -->
<div class="root">/ 오시는 길 /<hr style="height:2px; width:50%"></div>
<div class="date">서울특별시 중구 동호로 249 </div>
<div class="address">서울 신라호텔 웨딩홀 5층</div>
<div class="number">
call. 02-2233-3131
</div>
<div id="map" style="width:100%;height:350px; margin:20px auto;"></div>
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=본인 app 키&libraries=services"></script>
<script>
var mapContainer = document.getElementById('map'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
// 지도를 생성합니다
var map = new kakao.maps.Map(mapContainer, mapOption);
// 주소-좌표 변환 객체를 생성합니다
var geocoder = new kakao.maps.services.Geocoder();
// 주소로 좌표를 검색합니다
geocoder.addressSearch('서울 중구 동호로 249', function(result, status) {
// 정상적으로 검색이 완료됐으면
if (status === kakao.maps.services.Status.OK) {
var coords = new kakao.maps.LatLng(result[0].y, result[0].x);
// 결과값으로 받은 위치를 마커로 표시합니다
var marker = new kakao.maps.Marker({
map: map,
position: coords
});
// 인포윈도우로 장소에 대한 설명을 표시합니다
var infowindow = new kakao.maps.InfoWindow({
content: '<div style="width:150px;text-align:center;background-color:#2196F3;color:#fff;">서울 신라호텔</div>'
});
infowindow.open(map, marker);
// 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
map.setCenter(coords);
}
});
</script>
여러가지 리소스 사용
완성도를 높이기 위해 여러가지 리소스를 사용해보았다.
carousel이나 여러가지 넘김이나 밀리는 효과는 w3schools, 폰트는 구글폰트와 눈누, 지도는 카카오맵 api, 아이콘은 bootstrap, 알림창은 sweetalert를 사용해봤는데, sweetalert 정말 추천. (사용법 간단하니 구글링 ㄱㄱ)
완성본
만들 때는 아무생각 없었는데, 엄마아빠 리마인드 웨딩 촬영 당시 사진을 써서 ^^...모자이크 했다.
좋았던 점, 아쉬웠던 점
- 좋았던 점 : 모바일 청첩장에 게시판 기능을 넣으니 주변에서도 반응이 좋았다.
- 아쉬웠던 점 : 게시판을 삭제하고나 추가, 갱신할 때 스크롤이 자동으로 아래로 내려가게 구현을 하려고 했으나 자꾸 오류가 나서 해결하지 못했다. 다음에 다시 도전해볼 예정. 그리고 요즘 청첩장에 계좌번호도 넣는 경우도 있던데, 그 부분도 추가구현해 볼 예정이다.
'포트폴리오' 카테고리의 다른 글
[CNN] 졸음 운전 방지 AI 프로젝트 (0) | 2022.12.18 |
---|---|
React로 스마트 카트 시스템 개발하기 (기획부터 개발까지) (0) | 2022.08.20 |
범죄의 검거단서 분석하기 (0) | 2022.08.19 |