'SUMMERNOTE'에 해당되는 글 2건

스프링 게시판 만들기 1

홈페이지를 만들때 필수적으로 만드는게 게시판인거 같아요.

간단하게 게시판을 만들어 볼께요.

테이블은 이렇게 만들었어요. 

CREATE TABLE `tb_board` (
  `idx` int(11) NOT NULL AUTO_INCREMENT COMMENT '게시물 고유키값',
  `mdate` datetime DEFAULT NULL COMMENT '작성일',
  `title` varchar(50) DEFAULT NULL COMMENT '제목',
  `muuid` varchar(40) DEFAULT NULL COMMENT '고유id',
  `content` longtext DEFAULT NULL COMMENT '내용',
  `always` varchar(1) NOT NULL DEFAULT 'N' COMMENT '상단글인지',
  `m_delete` varchar(1) DEFAULT 'N' COMMENT '삭제여부',
  `division` varchar(50) DEFAULT NULL COMMENT '게시글구분',
  `mt_input_wdate` datetime DEFAULT NULL COMMENT '입력일',
  `mt_input_id` int(11) DEFAULT NULL COMMENT '입력ID',
  `mt_update_wdate` datetime DEFAULT NULL COMMENT '최종수정일',
  `mt_update_id` int(11) DEFAULT NULL COMMENT '최종수정ID',
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='게시판 기본형';

  게시글 구분으로 한테이블에 여러게시판들을 만들거에요. 

ALWAYS를 체크하면 목록으로 볼때 항상 맨위에 뜨게 만들거에요 그외엔 작성일 기준으로 최근글이 위로 오도록 할거에요.

uid는 첨부파일 게시판 생성시 사용할건데 지금은 그냥 만들어 놓기만 할께요.

일단 글쓰기 부터 해볼께요. 

@RequestMapping(value = "/write_e", method = RequestMethod.GET)
	public String write_e(HttpServletRequest request,HttpSession session, Model model) throws Exception {
		 Map<String, String[]> paramMap=request.getParameterMap();
		 Iterator keyData = paramMap.keySet().iterator();
		 CommonData dto = new CommonData();
		 while (keyData.hasNext()) {
	        String key = ((String)keyData.next());
	        String[] value = paramMap.get(key);
	        dto.put(key, value[0].toString());
	        model.addAttribute(key,value[0].toString());
	        smsp.print_String_no_line("key : " + key + ", value : " + value[0].toString());
		 }
		 model.addAttribute("issave","no");
		 Member vo = (Member) session.getAttribute("login");
		 if(dto.get("idx")!=null)
		 {
			 CommonData result_list = service.selectone(dto,"Board_Mapper.Board_editor_select");
			 smsp.print_CommonData(result_list);
			 Iterator keyData4 = result_list.keySet().iterator();
		     while (keyData4.hasNext()) {
		    	String key = ((String)keyData4.next());
		     	String value = result_list.get(key);          
		     	model.addAttribute(key,value);
		     }
		     if(vo!=null) //vo 로그인상태일때.
		     {
				 if(vo.idx==Integer.parseInt(result_list.get("mt_input_id")))
				 {
					 model.addAttribute("issave","yes");
				 }
				 if(vo.getMenu_lv()>9)
				 {
					 model.addAttribute("issave","yes");
				 }
		     }
		 }
		 else
		 {
			 String uuid = smsp.getUUID();//UUID.randomUUID();
			 model.addAttribute("uuid", uuid.toString());
			 model.addAttribute("issave","yes");
		 }
		 return "/board/write_e";
	 }

글쓰기로 들어가는 컨트롤러를 만들어요. 

내용은 써진 글일때 글쓴이는 issave값을 가져서 수정이 가능하고 레벨9이상의 메뉴권한을 가진사람도 수정권한을 가져요. 

아닐땐 아무런값없이 신규페이지에요. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@include file="../include/top.jsp"%>

  <!-- summernote -->
  <link rel="stylesheet" href="${pageContext.request.contextPath}/resources/AdminLTE/plugins/summernote/summernote-bs4.css">
  <!-- Summernote -->

<!-- Content Wrapper. Contains page content -->
  <div class="content-wrapper">
    <!-- Content Header (Page header) -->
    <div class="content-header">
      <div class="container-fluid">
        <div class="row mb-2">
          <div class="col-sm-6">
            <h1 class="m-0 text-dark"> 회원가입 <small>?</small></h1>
          </div><!-- /.col -->
          <div class="col-sm-6">
            <ol class="breadcrumb float-sm-right">
              <li class="breadcrumb-item"><a href="#">Home</a></li>
              <li class="breadcrumb-item active">회원가입</li>
            </ol>
          </div><!-- /.col -->
        </div><!-- /.row -->
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content-header -->

    <!-- Main content -->
    <div class="content">
      <div class="container-fluid">
        <div class="row">
          <div class="col-lg-12">
            <div class="card  card-primary card-outline">
              <div class="card-body">
                <h5 class="card-title"></h5>
                
                <div class="card-body register-card-body">
			      <p class="login-box-msg">글쓰기</p>
				      <table class="table table-write" id="add_mt">
						<colgroup>			
						<col style="width:120px" />
						<col style="width:*" />						
						</colgroup>
						<tr>						
							<th>작성일</th>
							<td>
								<input type="text" class="form-control" data-inputmask-alias="datetime" data-inputmask-inputformat="yyyy-mm-dd" data-mask="" im-insert="false"  id ="mdate" name="mdate" value="${mdate}"  disabled="disabled">
							</td>
						</tr>
						<tr>						
							<th>제목</th>
							<td><input type="text" class="form-control" id="title" name="title" placeholder="제목" value="${title}" required></td>
						</tr>
						<tr>						
							<th>공지설정</th>
							<td>
								<input type="checkbox" id="always" name="always" placeholder="공지설정"
								<c:if test="${always == 'Y'}">				
										 checked
										 </c:if> 
								> ${always}
							</td>						
						</tr>
						<tr>
							<th>내용</th>
							<td>
								<div id="summernote">${content}</div>
							</td>
						</tr>
					</table>			      
			      <input type="hidden" id="division" name="division" value="test1" />
			    </div>
			    
			    <div style="text-align: center;">
					<button title="목록" type="button" class="btn btn-outline-primary" onclick="move_list_note();">목록</button>
					<c:if test="${issave == 'yes'}">
					<button title="저장" type="button" id="a_save_btn" class="btn btn-outline-primary" onclick="save_note();">저장</button>
					<button title="삭제" type="button" class="btn btn-outline-primary" onclick="delete_note();">삭제</button>
					</c:if>
				</div>

                
              </div>
            </div>
		  </div>
        </div>
        <!-- /.row -->
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content -->
  </div>
  <!-- /.content-wrapper -->
  

<%@include file="../include/bottom.jsp"%>
<script src="${pageContext.request.contextPath}/resources/AdminLTE/plugins/summernote/summernote-bs4.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/AdminLTE/plugins/summernote/lang/summernote-ko-KR.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/AdminLTE/plugins/moment/moment.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/AdminLTE/plugins/inputmask/min/jquery.inputmask.bundle.min.js"></script>
//${pageContext.request.contextPath}/resources/AdminLTE/
<script>
$(function () {
    //Money Euro
    $('[data-mask]').inputmask()
	if($("#mdate").val()=='')
	{
		$("#mdate").val(getTimeStamp());
	}
    // Summernote
	$('#summernote').summernote({
	    lang: 'ko-KR', // default: 'en-US'
	   	height: 500,                 // set editor height
		minHeight: 500,             // set minimum height of editor
		maxHeight: 500,             // set maximum height of editor
		focus: true,                  // set focus to editable area after initializing summe
	  });
  })
</script>  

write_e.jsp 파일 내용이에요. 아직 저장하고 이런내용은 없어요. 

summernote 에딕터를 이용해서 글을 적어요.

일단 여기까지 해보세요 다음은 저장컨트롤러를 만들고 저장을 해볼께요. 

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

summernote img 태그 이미지 첨부 스프링

https://summernote.org/ 에가면 사용법등 잘설명되어 있어요.

저는 스프링에서 summernote를 사용하는 방법에대해서 정리할거에요.

일단 summernote를 다운로드 받으세요. 사이트에 가면 잘나와 있어요. 

	<link href="${pageContext.request.contextPath}/resources/editor/summernote.css" rel="stylesheet">
	<script src="${pageContext.request.contextPath}/resources/editor/summernote.js"></script>
	<!-- include summernote-ko-KR -->
	<script src="${pageContext.request.contextPath}/resources/editor/lang/summernote-ko-KR.js"></script>
    

받으셨으면 페이지에 첨부를 해요. 

페이지를 시작하는 부분에 $(document).ready(function() {});

아래코드를 첨부해요.

$('#summernote').summernote({
	    lang: 'ko-KR', // default: 'en-US'
	   	height: 500,                 // set editor height
		minHeight: 500,             // set minimum height of editor
		maxHeight: 500,             // set maximum height of editor
		focus: true,                  // set focus to editable area after initializing summe
		callbacks: {
          onImageUpload: function(files, editor, welEditable) {
            for (var i = files.length - 1; i >= 0; i--) {
              sendFile(files[i], this);
            }
          },
          onChange: function(contents, $editable) {
              console.log('onChange:', contents, $editable);
             
              new_img_list=$(".note-editable .sn_insert_img");
              if(old_img_list!='' &&new_img_list!='')
              {
              	note_image_sync(old_img_list,new_img_list);
              }
              old_img_list= $(".note-editable .sn_insert_img");
              
            },
          onBlur: function() {
              console.log('Editable area loses focus');
            },
          onFocus: function() {
              console.log('Editable area is focused');
            }
        }
	  });
	$("#summernote").summernote({
	    onMediaDelete : function($target, editor, $editable) {
	         alert($target.context.dataset.filename);         
	         $target.remove();
	    }
	}); 

섬머노트 페이지에 가면 설명이 잘되어 있어서 설명은 안하겠어요. 여기서 onImageUpload 부분을 구현해줘야 해요. 

sendFile부분을 구현해야해요. 

function sendFile(file, el) {
    var form_data = new FormData();
    form_data.append('file', file);
    $.ajax({
      data: form_data,
      headers : {
			'X-CSRF-TOKEN': $("#csrf_token").val()
		},
      type: "POST",
      url: '/admin/chart/image_upload',
      cache: false,
      contentType: false,
      enctype: 'multipart/form-data',
      processData: false,
      async: false
    }).done(function( msg ) {
        if(msg.result=='IMAGE_OK')
        {
	        var url = msg.url;
	        id = msg.id;        
	        $(el).summernote('editor.insertImage', url,fun_summernote_imgcallback);
	        $('#imageBoard > ul').append('<li><img src="'+url+'" class="summernoteimg_obj" id="'+id+'" width="100%" height="100%"/></li>');
        }
        else
    	{
        	showmessage("알림","이미지 파일이 아닙니다.",2000,'');
    	}
    });
  }

저는 이미지 파일을 db에 보관을 해요. 

image_upload부분은 이렇게 해요. 

@ResponseBody
		@RequestMapping(value ="/image_upload", method=RequestMethod.POST, produces = "application/json;charset=UTF-8")
		public Map<String, String> update_file_upload(MultipartFile file,HttpServletRequest request)throws Exception{
			Map<String, String[]> paramMap=request.getParameterMap();
			Iterator keyData = paramMap.keySet().iterator();
			CommonData dto = new CommonData();
			while (keyData.hasNext()) {
			    String key = ((String)keyData.next());
			    String[] value = paramMap.get(key);
			    dto.put(key, value[0].toString());        
			    smsp.print_String("key : " + key + ", value : " + value[0].toString());
			} 
			MediaUtils MediaUtils = new MediaUtils();
			String formatName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
			MediaType mType = MediaUtils.getMediaType(formatName);
			BufferedImage resizeimg;
			if(mType!=null)
			{
				BufferedImage srcImg = ImageIO.read(file.getInputStream()); 
				/*
			    if(srcImg.getWidth()>1920) //사이즈 조절 할때
			    {
			    	smsp.print_String("사이즈 조절 1920");
			    	resizeimg = Scalr.resize(srcImg
			    			, Scalr.Method.QUALITY
			    			, Scalr.Mode.FIT_TO_WIDTH
			    			, 1920
			    			,Scalr.OP_ANTIALIAS);
			    	ByteArrayOutputStream baos_re = new ByteArrayOutputStream();
			 	    boolean foundWriter_re = ImageIO.write(resizeimg, formatName.toLowerCase(), baos_re);
			 	    baos_re.flush();
			 		byte[] imageInByte_re = baos_re.toByteArray();
			 		dto.put("mt_contentlength",baos_re.toByteArray().length);
			 		dto.put("mt_data", imageInByte_re);
			 		baos_re.close();
			    }
			    else //사이즈 조절안할때.
			    */ 
			    {	
			    	smsp.print_String("사이즈 조절안함. 1920");
			    	dto.put("mt_contentlength",file.getBytes().length);
			 	    dto.put("mt_data", file.getBytes());
			    }	   
			    BufferedImage destImg = 
			            Scalr.resize(srcImg, 
			            		Scalr.Method.BALANCED, 
			                180,180
			                ,Scalr.OP_ANTIALIAS);
			    ByteArrayOutputStream baos = new ByteArrayOutputStream();
			    boolean foundWriter = ImageIO.write(destImg, "png", baos);
				baos.flush();
				byte[] imageInByte = baos.toByteArray();
				dto.put("mt_s_data", imageInByte);
				baos.close();
			}
			Map<String, String> result = new HashMap<>();
			result.put("result", "NOT_AN_IMAGE");
			if(mType!=null)
			{
			    dto.put("mt_filename",file.getOriginalFilename());
			    dto.put("mt_type",file.getContentType());
			    HttpSession session = request.getSession();
			    Member vo = (Member) session.getAttribute("login");
			    dto.put("mt_input_id", vo.idx);
			    dto.put("mt_update_id", vo.idx);
			    first_service.insert(dto, "File_UpDown_Mapper.insert_editor_image_upload");
			    int idx= first_service.listSearchCount(dto, "File_UpDown_Mapper.select_editor_image_upload");
				result.put("result", "IMAGE_OK");
			    String url = "/editor/get_editor_image/?idx="+idx;
			    String id = ""+idx;
			    result.put("url", url);
			    result.put("id", id);
			    }
		    return result;
		}

db에 바로 넣고 있어요. 

db의 테이블은 이렇게 생겼어요. 

CREATE TABLE `editor_image_table` (
  `idx` int(11) NOT NULL AUTO_INCREMENT COMMENT '게시물 고유키값',
  `mt_uuid` varchar(40) DEFAULT NULL,
  `mt_contentlength` int(11) DEFAULT NULL COMMENT '파일사이즈.',
  `mt_filename` varchar(100) DEFAULT NULL COMMENT '이름',
  `mt_type` varchar(100) DEFAULT NULL COMMENT '파일타입',
  `mt_data` longblob DEFAULT NULL COMMENT '파일내용',
  `mt_s_data` longblob DEFAULT NULL COMMENT '축소파일내용',
  `mt_input_wdate` datetime DEFAULT NULL COMMENT '입력일',
  `mt_input_id` bigint(20) DEFAULT NULL COMMENT '입력ID',
  `mt_update_wdate` datetime DEFAULT NULL COMMENT '최종수정일',
  `mt_update_id` bigint(20) DEFAULT NULL COMMENT '최종수정ID',
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='파일정보';

쿼리부분입니다. 

<!-- 이미지파일 업로드 -->
	<insert id="insert_editor_image_upload">	
		INSERT INTO editor_image_table (
						   mt_filename						
						 , mt_type
						 , mt_data
						 <if test="mt_s_data != null">
						 , mt_s_data
						 </if>
						 <if test="uid != null">
						 , mt_uuid
						 </if>
						 , mt_contentlength
						 , mt_input_wdate
						 , mt_input_id
						 , mt_update_wdate
						 , mt_update_id
						 ) 
				     VALUES (
				           #{mt_filename}				         	
				         , #{mt_type}
				         , #{mt_data}
				         <if test="mt_s_data != null">
				         , #{mt_s_data}
				         </if>
				         <if test="uid != null">
						 , #{uid}
						 </if>
				         , #{mt_contentlength}
				         , now()		          
				         , #{mt_input_id}
				         , now()
				         , #{mt_update_id}	         
				         )
	</insert>

이상입니다.

블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,