안녕하세요 세기무민입니다.
우선 제가 진행하려는 화면은 아래의 포스팅 화면을 기반으로 진행하였습니다.
👇👇👇👇👇👇👇👇👇 전에 진행했던 포스팅을 보고 싶다면?! 👇👇👇👇👇👇👇👇👇
👇👇👇👇👇👇👇👇👇 현재까지 진행한 내용들은 아래의 주소에서 확인 가능합니다. 👇👇👇👇👇👇👇👇👇
1. 화면
우선 블로그 화면에 처음 들어오면 데이터가 없기 때문에 새로운 글을 작성해야 한다.
따라서 글 작성 화면(NEW POST 버튼 클릭)으로 넘어가보자
New Post 화면으로 넘어오면 블로그에 작성할 내용들을 작성해줍니다.
- 현재는 1차 버전으로 이미지 링크 대신 이미지 파일 업로드 등 다양한 기능들은 추후에 수정할 예정
작성을 완료하면 아래와 같이 Blog 화면으로 넘어오며 데이터가 추가된 것을 볼 수 있다.
추가적으로 Blog 화면에서 read More을 클릭시 내용들을 자세히 볼 수 있다. (이미지는 추후 수정 예정)
2. 로직 및 코드
우선 로직에서 추가된 Class 파일과 Jsp 파일은 위와 같습니다.
우선 코드는 천천히 다뤄보도록 하고 이번 포스팅에서는 우선 포스팅을 새로 생성하는 화면에 대해 다뤄보겠습니다.
1. newPost.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>[sg-moomin] lumin_daily </title>
<%@include file="footer/bootstrap.jsp"%>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
<style>
.koreanFont {
font-family: 'Jua', sans-serif
};
</style>
</head>
<body>
<div id="colorlib-page">
<%@include file="footer/header.jsp"%>
<div id="colorlib-main">
<section class="ftco-section ftco-bread">
<div class="container">
<div
class="row no-gutters slider-text justify-content-center align-items-center">
<div class="col-md-8 ftco-animate">
<p class="breadcrumbs">
<span class="mr-2"><a href="index">Home</a></span> <span>PortPoilo</span>
</p>
<h1 class="bread">Lumin Blog</h1>
</div>
</div>
</div>
</section>
<section class="ftco-section contact-section">
<div class="container">
<div class="col-md-12 mb-4">
<h2 class="h3 font-weight-bold">New Post</h2>
</div>
<div class="row block-9">
<div class="col-md-12 d-flex">
<form name="newCreatePost" id="newCreatePost" method="post" class="bg-light p-5 contact-form">
<div class="form-group">
<h5 class="koreanFont">블로그 포스트 제목</h5>
<input type="text" class="form-control" id="blogmaintitle" name="blogmaintitle" placeholder="postMainTitle & blogMainTitle">
</div>
<div class="form-group">
<h5 class="koreanFont">블로그 포스트 소제목</h5>
<input type="text" class="form-control" id="blogsntitle" name="blogsntitle"
placeholder="blogSnTitle & postSnTitle">
</div>
<div class="form-group">
<h5 class="koreanFont">블로그 포스트 태그</h5>
<input type="text" class="form-control" id="blogtag" name="blogtag" placeholder="blogTag&postTag">
</div>
<div class="form-group">
<h5 class="koreanFont">이미지 링크</h5>
<input type="text" class="form-control" id="imgtitle" name="imgtitle" placeholder="imgTitle">
</div>
<div class="form-group">
<h5 class="koreanFont">사이트 링크</h5>
<input type="text" class="form-control" id="posturl" name="posturl" placeholder="postUrl">
</div>
<div class="form-group">
<h5 class="koreanFont">블로그 포스팅 내용</h5>
<textarea name="blogsn" id="blogsn" cols="30" rows="7" class="form-control"
placeholder="blogsn"></textarea>
</div>
<div class="form-group">
<input type="button" value ="create new post" class="btn btn-primary py-3 px-5" onclick="createPost(); return false;" >
</div>
</form>
</div>
</div>
</div>
</section>
<%@include file="footer/footer.jsp"%>
</div>
</div>
<script type="text/javascript">
function createPost(){
var successMsg = "저장되었습니다";
var errorMsg = "저장 중 오류가 발생하였습니다.";
var dataset = {};
dataset["blogmaintitle"] = $("#blogmaintitle").val();
dataset["blogsntitle"] = $("#blogsntitle").val();
dataset["blogtag"] = $("#blogtag").val();
dataset["blogsn"] = $("#blogsn").val();
dataset["imgtitle"] = $("#imgtitle").val();
dataset["posturl"] = $("#posturl").val();
$.ajax({
type: "POST",
url:"<%=request.getContextPath()%>/newPost",
data: JSON.stringify(dataset),
dataType: "text",
contentType:"application/json;charset=UTF-8",
beforeSend : function() {
console.log("start");
},
success: function (data, status, xhr) {
console.log("success");
alert(successMsg);
window.location.href = data;
},
error: function (e) {
console.log("ERROR : ", e);
alert(errorMsg);
}
});
}
</script>
</body>
</html>
우선 한글 폰트를 추가해주기 위해 KoreaFont를 만들어줍니다.
폰트 추가하는 방법에 대해서는 위의 포스팅에서 자세하게 다뤄놨습니다.
폼을 이용해서 입력받은 데이터를 Java로 넘겨주도록 구현했는데 Jquery에 대해서 좀 더 확인해보겠습니다.
<!--
form 입력 및 버튼
-->
<form name="newCreatePost" id="newCreatePost" method="post" class="bg-light p-5 contact-form">
<input type="button" value ="create new post" class="btn btn-primary py-3 px-5" onclick="createPost(); return false;" >
<!--
클릭 시 이벤트
-->
<script type="text/javascript">
function createPost(){
var successMsg = "저장되었습니다";
var errorMsg = "저장 중 오류가 발생하였습니다.";
var dataset = {};
dataset["blogmaintitle"] = $("#blogmaintitle").val();
dataset["blogsntitle"] = $("#blogsntitle").val();
dataset["blogtag"] = $("#blogtag").val();
dataset["blogsn"] = $("#blogsn").val();
dataset["imgtitle"] = $("#imgtitle").val();
dataset["posturl"] = $("#posturl").val();
$.ajax({
type: "POST",
url:"<%=request.getContextPath()%>/newPost",
data: JSON.stringify(dataset),
dataType: "text",
contentType:"application/json;charset=UTF-8",
beforeSend : function() {
console.log("start");
},
success: function (data, status, xhr) {
console.log("success");
alert(successMsg);
window.location.href = data;
},
error: function (e) {
console.log("ERROR : ", e);
alert(errorMsg);
}
});
}
</script>
</body>
</html>
우선 버튼을 클릭시 createPost의 함수를 호출해줍니다.
해당 함수에서는 Form에 입력한 데이터를 기준으로 데이터 셋을 만든 뒤 Json 형태로 Java에 넘겨줍니다.
넘겨 준 뒤 성공하는 경우 Java로부터 받은 data의 경로로 이동하도록 구현했습니다.
번외로 footer.jsp와 bootstrap.jsp 파일은 링크나 기본적으로 화면에서 공통으로 사용되는 부분을 따로 분리해놨습니다.
2. blogCtl.class
@Controller
@RestController
@RequiredArgsConstructor
public class blogCtl {
@Autowired
public blogPostEntityService blogPostEntitySvc;
@Autowired
public blogEntityService blogEntitySvc;
@Autowired
public blogCreateService blogCreateSvc;
@RequestMapping(value="/newPost", method=RequestMethod.GET)
public ModelAndView newPost(ModelAndView M) {
M.setViewName("newPost");
return M;
}
@RequestMapping(value="/newPost", method=RequestMethod.POST)
@ResponseBody
public String newPost(ModelAndView M, @RequestBody Map<String, Object> param) throws IOException {
blogVo result = blogCreateSvc.saveBlog(param);
return "blog";
}
}
위의 newPost.jsp에서 POST 방식으로 넘겨준 데이터를 Controller에서 받아줍니다.
흐름은 Contoller에서 받은 뒤 Service -> Repository 흐름으로 데이터를 넘겨줘서 처리하게 됩니다.
3.blogEntity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name="blog")
public class blogEntity {
@Id
@Column(nullable = false)
private String blogid;
@Column(nullable = false, length = 500)
private String blogmaintitle;
@Column(nullable = false, length = 100)
private String blogsntitle;
@Column(nullable = false, length = 500)
private String blogsn;
@Column(nullable = false, length = 100)
private String blogtag;
@Column(nullable = false, length = 100)
private String imgtitle;
@Column(nullable = false, length = 100)
private String postid;
@Column(nullable = false)
private String regdt;
@Column(nullable = false, length = 50)
private String regid;
@Column(nullable = false)
private String uptdt;
@Column(nullable = false, length = 50)
private String uptid;
}
blog에 대한 엔티티를 생성해줍니다 (blog 테이블의 컬럼과 동일).
4.blogPostEntity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity(name="blogpost")
public class blogPostEntity {
@Id
@Column(nullable = false)
private String postid;
@Column(nullable = false, length = 500)
private String postmaintitle;
@Column(nullable = false, length = 100)
private String postsntitle;
@Column(nullable = false, length = 1000)
private String postsn;
@Column(nullable = false, length = 300)
private String posturl;
@Column(nullable = false, length = 300)
private int postlvl;
// private int postlvl;
@Column(nullable = false, length = 300)
private int postupperlvl;
// private int postupperlvl;
@Column(nullable = false)
private String regdt;
@Column(nullable = false, length = 50)
private String regid;
@Column(nullable = false)
private String uptdt;
@Column(nullable = false, length = 50)
private String uptid;
}
blogPost에 대한 엔티티를 생성해줍니다 (blogPost테이블의 컬럼과 동일).
5. blogCreateService.class
@Service
@RequiredArgsConstructor
public class blogCreateServiceImpl implements blogCreateService {
@Autowired
private blogRepository blogRepository;
@Autowired
private blogPostRepository blogPostRepository;
@Override
public blogVo saveBlog(Map<String, Object> param) {
/* Map -> Object 변환 */
blogVo vo = new blogVo();
vo.setBlogMainTitle((String)param.get("blogmaintitle"));
vo.setBlogSnTitle((String)param.get("blogsntitle"));
vo.setBlogTag((String)param.get("blogtag"));
vo.setBlogSn((String)param.get("blogsn"));
vo.setImgTitle((String)param.get("imgtitle"));
vo.setPostUrl((String)param.get("posturl"));
vo.setUsrId("sg-moomin");
String defCd = "00000000";
// 1. Blog Id 생성(채번)
String blogCd = blogRepository.selectMaxBlogId();
String blogSequence = "";
if(blogCd == null || blogCd == "" ) {
blogSequence = defCd;
} else {
blogSequence = blogCd.substring(1);
}
int blogNo = Integer.parseInt(blogSequence) + 1;
String blogTmp = String.format("%08d", blogNo);
String blogId = "B" + blogTmp;
vo.setBlogId(blogId);
// 2. Post Id 생성(채번)
String postCd = blogPostRepository.selectMaxPostId();
String postSequence = "";
if(postCd == null || postCd == "" ) {
postSequence = defCd;
} else {
postSequence = postCd.substring(1);
}
int postNo = Integer.parseInt(postSequence) + 1;
String postTmp = String.format("%08d", postNo);
String postId = "P" + postTmp;
vo.setPostId(postId);
// insert
// int result = blogRepository.saveBlog();
// 3. Blog 내용 Insert
blogEntity blogEty = blogEntity.builder()
.blogid(vo.getBlogId())
.blogmaintitle(vo.getBlogMainTitle())
.blogsn(vo.getBlogSn())
.blogsntitle(vo.getBlogSnTitle())
.blogtag(vo.getBlogTag())
.imgtitle(vo.getImgTitle())
.postid(vo.getPostId())
.regid(vo.getUsrId())
.uptid(vo.getUsrId())
.build();
blogRepository.save(blogEty);
// 3. Post 내용 Insert
blogPostEntity postEty = blogPostEntity.builder()
.postid(vo.getPostId())
.postmaintitle(vo.getBlogMainTitle())
.postsn(vo.getBlogSn())
.posturl(vo.getPostUrl())
.postlvl(vo.getPostLvl())
.postupperlvl(vo.getPostUpperLvl())
.regid(vo.getUsrId())
.uptid(vo.getUsrId())
.build();
blogPostRepository.save(postEty);
return vo;
}
위의 코드처럼 newPost로부터 입력한 데이터를 저장해줍니다.
채번의 경우는 DB에서 시퀀스를 이용하여 만들어도 무관하지만 우선은 위의 방식처럼 만들어봤습니다.
이 방법보다는 개인적으로 시퀀스를 이용하는을 추천합니다.
그리고 넘겨받은 값과 채번한 뒤 해당 값들은 Insert 해주면 됩니다.
builder와 build를 통해 Entity 객체에 데이터를 넣어준 뒤 JAP 내장 함수인 Save를 이용하여 Insert를 진행해주면
DB에 데이터가 들어가게 됩니다.
마지막으로 DB에 대해서는 다음 포스팅에서 다뤄보겠습니다.
3. 마무리
사실 이번 포스팅에 모든 내용들을 담아볼 생각이였으나 코드를 다루는 양이 너무 많아질 것 같아서
다음 포스팅에서 추가로 포스팅 하겠습니다.(....사실 기능적인 코드는 없어서.....다음 포스팅이 허전할 수도...)
다음 포스팅에서 다룰 내용은 아래와 같습니다.
- DB 테이블 정리
- blog.jsp / blogPost.jsp와 관련된 내용
다음 포스팅에서는 더 유익한 정보로 찾아오겠습니다.
'Programing > Java & Spring' 카테고리의 다른 글
Java 예외(Exception) 처리 이론 정리 (0) | 2022.10.19 |
---|---|
세무민의 코딩일기 : 포트폴리오 화면에 블로그 기능 추가하기 2탄 [포트폴리오 사이트 제작하기 4탄] (0) | 2022.02.13 |
(Java&Spring) JPQL 활용하기[포토폴리오 싸이트 제작하기 2탄 - 세무민의 코딩일기] (0) | 2022.01.04 |
(JAVA) JPA에 대해서 알아보자 [포토폴리오 싸이트 제작하기 1탄 - 세무민의 코딩일기] (0) | 2021.10.14 |
세무민의 코딩일기 : 개발자가 객체 설계시 염두해야 할 사항은? (0) | 2021.06.20 |