1. 게시판 삽입
2. 게시판 삭제
3. 게시판 수정
4. 게시판 상세페이지
5. 좋아요
6. 팔로잉(작가에 대해서만)
이 게시판에서는 게시판의 삽입방법의 구현을 게시해보고자 한다.
스마트에디터 2.0 (이미지 업로드가 되는 버전)
스마트 에디터는 업그레이드가 되면서 이미지 업로드를 지원하지 않는 버전이 생겼다. 나는 이번 프로젝트에서 사용할 버전을 2.8.2버전을 사용하였다.
스마트에디터를 적용할 페이지의 textarea
업로드할 프로젝트
스마트 에디터를 구현하려면 먼저 css와 js를 연동해야한다. 연동해야할 종류는 다음 이미지와 같다.
파일의 위치는 webapp의 resources내부에 넣어주면 된다. 그렇게 github에서 받아온 버전을 넣어주면 잘 실행하는 화면을 볼 수 있다. 이렇게 잘 넣어주면 우리는 이제 textarea를 만질 수 있다.
<form id = "noticeWriteForm" action ="../write/${boardCode}?type=update&no=${detail.boardId}" method ="post" class = "widthfull">
<!-- 제목 -->
<div id = "board_Write_title">
<input id = "title" name = "title" type ="text" placeholder="제목" class ="boardInputTitle" value = "${detail.boardTitle}">
</div>
<!-- 본문 -->
<div id ="smarteditor">
<textarea name="smartEditor" id="smartEditor" rows="20" cols="10" style="width: 500px; height:400px;">${detail.boardContent}</textarea>
</div>
<!-- 작성 버튼 -->
<div class ="board_btn_area">
<input type="button" id="savebutton" value="작성" />
</div>
</form>
form을 작성하여 나는 textarea를 작성하였다. action부분에는 상대경로로 되어있지만 만약 여러분이 contextPath를 맨 처음 전처리기에서 구현하여 어플리케이션에 적용하였다면 ${contextPath}/경로를 써서 사용할 수 있을 것이다.
경로를 설정하기에 나도 애먹은 부분이 있으니 나중에 따로 경로에 대한 문제는 적어보도록 하겠다.
거두절미하고, 이렇게 textarea를 만들고 smartEditor라는 id를 주었다. 나는 이 아이디를 밑에서 script를 통해 연결을 할 것이다.
<script>
var oEditors = [];
nhn.husky.EZCreator.createInIFrame({
oAppRef : oEditors,
elPlaceHolder : "smartEditor", //저는 textarea의 id와 똑같이 적어줬습니다.
sSkinURI : "${contextPath}/resources/static/SmartEditor2Skin.html", //경로를 꼭 맞춰주세요!
fCreator : "createSEditor2",
htParams : {
// 툴바 사용 여부 (true:사용/ false:사용하지 않음)
bUseToolbar : true,
// 입력창 크기 조절바 사용 여부 (true:사용/ false:사용하지 않음)
bUseVerticalResizer : false,
// 모드 탭(Editor | HTML | TEXT) 사용 여부 (true:사용/ false:사용하지 않음)
bUseModeChanger : false
}
});
$(function() {
$("#savebutton").click(function() {
oEditors.getById["smartEditor"].exec("UPDATE_CONTENTS_FIELD", []);
//textarea의 id를 적어줍니다.
var title = $("#title").val();
var content = document.getElementById("smartEditor").value;;
if (title == null || title == "") {
alert("제목을 입력해주세요.");
$("#title").focus();
return;
}
if(content == "" || content == null || content == ' ' ||
content == '<br>' || content == '<br/>' || content == '<p> </p>'){
alert("본문을 작성해주세요.");
oEditors.getById["smartEditor"].exec("FOCUS"); //포커싱
return;
} //이 부분은 스마트에디터 유효성 검사 부분이니 참고.
console.log(content);
var result = confirm("작성하시겠습니까?");
if(result){
alert("작성이 완료되었습니다.");
$("#noticeWriteForm").submit();
}else{
return;
}
});
})
</script>
elPlaceholder에 textarea를 연결시키고
sSkinURI : "${contextPath}/resources/static/SmartEditor2Skin.html"
textarea와 연동될 스킨을 덧입히면 되는데 이것은 static내부에 있을 테니 그대로 쓰면 제대로 먹힐 것이다. 나머지는 똑같이 해도 된다.
함수 부분에서 버튼 부분과 연동해서 유효성 검사를 진행시키면 된다. 추가할 문을 작성하고 요소의 아이디 값과 연동시키면 이제 연결은 끝이 났다.
하지만 아직 이미지 요소를 삽입할 수는 없다. 이미지 요소를 넣으려면 우리가 스킨을 입히려고 사용했던 html인 SmartEdiotr2Skin.html을 살펴보면 된다.
열었을 때 오픈 코드의 전경이다. 우리는 여기서 이미지 업로드 부분과 연관되어있는 AttachQuickPhoto.js를 살펴볼 것이다.
AttachQuickPhoto.js의 일부 코드이다. 다른 부분은 건드리지 않아도 된다 그리고 우리가 볼 부분은 ../sample/photo_uploader/photo_uploader.html이다.
photo_uploader.html
벌써부터 어질어질 하지만 우리가 봐야할 부분은 이곳과 연결된
<script type="text/javascript" src="attach_photo.js" charset="utf-8"></script>
딱 두군데이니 그곳만 보도록 하자.
먼저 파일을 업로드하는 형식은 두가지가 있다.
다중 이미지 업로드는 끌어다 놓는 스타일로, 기능을 제공하는 브라우저만이 이 기능을 사용할 수 있다고 한다. 나는 크롬에서 사용하기 때문에 다중과 단일 전부 구현할 예정이다.
sUploadURL에 우리가 controller로 가져올 경로를 써주면 된다. 이 경로에는 다음과 같이 코드를 작성해주면 된다.
//사진 단일 업로드
@PostMapping("/write/img")
public String photoUpload(HttpServletRequest request, PhotoSmart vo) {
String callback = vo.getCallback();
String callback_func = vo.getCallback_func();
String file_result = "";
try {
if(vo.getFiledata() != null && vo.getFiledata().getOriginalFilename()!=null && ! vo.getFiledata().getOriginalFilename().equals("")) {
//파일이 존재하면
String original_name = vo.getFiledata().getOriginalFilename();
String ext = original_name.substring(original_name.lastIndexOf(".")+1);
//파일 기본경로
String defaultPath = request.getSession().getServletContext().getRealPath("/");
//파일 기본경로_상세경로
String path = defaultPath + "resources" + File.separator + "images" + File.separator +"boardImg" + File.separator;
File file = new File(path);
if(!file.exists()) {
file.mkdirs();
}
String realname = UUID.randomUUID().toString() + "." + ext;
vo.getFiledata().transferTo(new File(path+realname));
file_result += "&bNewLine=true&sFileName=" +original_name + "&sFileURL=/stroke/resources/images/boardImg/"+realname;
}else {
file_result+= "&errstr=error";
}
}catch(Exception e) {
e.printStackTrace();
}
return "redirect:" + callback + "?callback_func="+callback_func+file_result;
}
파일 경로를 작성하고 파일 경로에 업로드 하게끔 transferTo를 작성한다.
해당하는 함수를 찾고 sUploadURL에 프로젝트 서버가 실행하는 URL를 설정하면 된다. 설정한 URL의 내용은 다음과 같다.
//사진 멀티 업로드
@PostMapping("/multiphotoUpload")
public void multiplePhotoUpload(HttpServletRequest request, HttpServletResponse response) {
try {
String sFileInfo = "";
String filename = request.getHeader("file-name");
String filename_ext = filename.substring(filename.lastIndexOf(".")+1);
filename_ext = filename_ext.toLowerCase();
String dftFilePath = request.getSession().getServletContext().getRealPath("resources");
//String dftFilePath = "\\art_stroke";
logger.info(dftFilePath);
// application 내장 객체 얻어오기
String filePath = dftFilePath + File.separator + "images" + File.separator+"boardImg" +File.separator;
logger.info(filePath);
File file = new File(filePath);
if(!file.exists()) {
file.mkdirs();
}
String realFileNm = "";
SimpleDateFormat formatter = new SimpleDateFormat("yyyyHHmmss");
String today = formatter.format(new java.util.Date());
realFileNm = today + UUID.randomUUID().toString() + filename.substring(filename.lastIndexOf("."));
String rlFileNm = filePath + realFileNm;
//서버에 파일쓰기
InputStream is = request.getInputStream();
OutputStream os = new FileOutputStream(rlFileNm);
int numRead;
byte b[] = new byte[Integer.parseInt(request.getHeader("file-size"))];
while((numRead = is.read(b,0,b.length)) != -1) {
os.write(b,0,numRead);
}
if(is != null) {
is.close();
}
os.flush();
os.close();
sFileInfo+="&bNewLine=true";
sFileInfo += "&sFileName="+ filename;;
sFileInfo += "&sFileURL="+"/stroke/resources/images/boardImg/"+realFileNm;
PrintWriter print = response.getWriter();
print.print(sFileInfo);
print.flush();
print.close();
}catch(Exception e) {
e.printStackTrace();
}
}
파일 마다 함수가 실행하게끔 유도하여 서버에 파일을 쓰도록 Stream을 구현하여 파일 사이즈를 보고 파일이 있으면 flush를 통해 파일을 서버에 업로드하는 방식으로 구현 후에 textarea에 표현하기 위해 print를 통해 화면에 구현하였다.
이 과정을 통해 이미지를 업로드 하고 게시판을 등록할 수 있다.
게시판 삽입 과정은 다음 시간에 계속 진행하겠다.