학원/spring

1.15 (spring tiles (db연동)- 회원관리 끝 / 게시판 시작)

쿠룽지 2024. 1. 15. 20:52
728x90
반응형

 

 

 

<마이페이지 기본 설정>

 

 

 

 

<마이페이지 사진 설정 카메라 사진 넣기>

마이페이지 속 이미지가 static 안에 있어야 하기 때문에 그 안에 폴더 만들고 저장할 것임

src/main/resources

static

images (folder)

 

mbox에서 camera 사진 다운 받은 후 images 에 넣기

 

 

 

 

 

 

 

한 건의 레코드 읽어와서 정보 뿌리기

kr.spring.member.dao

MemberMapper.java

@Select("SELECT * FROM spmember JOIN spmember_detail USING(mem_num) WHERE mem_num=#{mem_num}")
public MemberVO selectMember(int mem_num);//한건의 레코드 반환

 

 

 

 

 

 

 

 

Service 파일에서 처리하기

kr.spring.member.service

MemberServiceImpl

@Override
public MemberVO selectMember(int mem_num) {
    return memberMapper.selectMember(mem_num);
}

 

 

 

 

 

 

 

컨트롤러에서 호출하기

kr.spring.member.controller

MemberController

/*=======================
 *       MyPage
 *======================= */
@RequestMapping("/member/myPage")
public String process(HttpSession session,Model model) {
    MemberVO user = (MemberVO)session.getAttribute("user");
    //회원 정보
    MemberVO member = memberService.selectMember(user.getMem_num()); //한건의 레코드 읽어오기

    log.debug("<<회원 상세 정보>> : " + member); //member -> toString 동작 (내용 출력)
    model.addAttribute("member", member);

    return "myPage";
}

 

 

 

 

 

 

 

myPage body부분 view 수정

views

member

memberView.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 내용 시작 -->
<div class="page-main">
	<h2>회원 상세 정보 <input type="button" value="회원 정보 수정" onclick="location.href='update'"></h2>
	<ul>
		<li>이름 : ${member.name}</li>
		<li>별명 : ${member.nick_name}</li>
		<li>전화번호 : ${member.phone}</li>
		<li>이메일 : ${member.email}</li>
		<li>우편번호 : ${member.zipcode}</li>
		<li>주소 : ${member.address1} ${member.address2}</li>
		<li>가입날짜 : ${member.reg_date}</li>
		<c:if test="${!empty member.modify_date}">
		<li>정보 수정일 : ${member.modify_date}</li>
		</c:if>
	</ul>
</div>
<!-- 내용 끝 -->

=============================
restart 후 읽어오면 화면에
화면 상세 정보 출력됨

 

 

 


 

 

 

 

 

<프로필 사진 저장하기 - db저장>

 

 

 

프로필 사진이 없을 시 이전에 사용했던 face.png로 기본 이미지 처리할 것임

mbox에서 face.png 받아서 images 에 넣기

 

이미지 업로드 시 spmember_detail에 업로드

마이바티스는 byte[] 배열 단위만 처리 가능 (ajax를 사용해야 하니까 jquery 필요)

 

 

template

nav_mypage.jsp

<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/member.profile.js"></script>

아래에 jquey 구문 붙여주기

 

 

 

 

 

 

 

java script는 하나씩 확인하는 게 에러 확인에 더 좋음

일단 더 편하게 확인하기 위해 nav_mypage.jsp 에서 

<img src="${pageContext.request.contextPath}/images/face.png" width="200" height="200" class="my-photo">

라고 기본 이미지 face.png로 설정하기

 

 

 

 

 

1. 카메라 아이콘 클릭 시 파일선택, 전송, 취소 버튼 출력하기

src/main/resources
static
js
member.profile.js (javascript file)

$(function(){
	//My페이지 프로필 사진 등록 및 수정
	//수정 버튼 이벤트 처리
	$('#photo_btn').click(function(){
		$('#photo_choice').show();
		$(this).hide();
	});
	
});

 

 

 

 

 

 

 

 

2. 미리보기 후 취소 버튼 누르면 기본 이미지로 변경되는 것까지 확인

src/main/resources
static
js
member.profile.js (javascript file)

$(function(){
	//My페이지 프로필 사진 등록 및 수정
	//수정 버튼 이벤트 처리
	$('#photo_btn').click(function(){
		$('#photo_choice').show();
		$(this).hide();
	}); // end of click
	
	//처음 화면에 보여지는 이미지 읽기
	//업데이트 하려다가 취소 누르면 다시 원래 이미지로 돌아가야하는데 그걸 위해서 저장해놓는 거임
	let photo_path = $('.my-photo').attr('src');
	let my_photo; //업로드 하고자 선택한 이미지 저장
	//파일 선택 이벤트 연결
	$('#upload').change(function(){
		my_photo = this.files[0]; //선택한 이미지 저장
		
		//선택한 파일이 없을 때에
		if(!my_photo){
			$('.my-photo').attr('src',photo_path);
			return;
		}
		
		//파일 업로드 처리 시 용량체크
		if(my_photo.size > 1024*1024){ //1mb까지만 업로드
			alert(Math.round(my_photo.size/1024) + 'kbytes(1024kbytes까지만 업로드 가능)');
			$('.my-photo').attr('src',photo_path);
			$(this).val(''); //파일명 지우기
			return;
		}
		
		//이미지 미리보기 처리
		let reader = new FileReader();
		reader.readAsDataURL(my_photo);
		
		reader.onload=function(){
			$('.my-photo').attr('src',reader.result);
		};
	}); // end of change
	
	//파일 업로드 처리
	$('#photo_submit').click(function(){
		if($('#upload').val()==''){
			alert('파일을 선택하세요!');
			$('#upload').focus();
			return;
		}
		//서버에 전송할 파일 선택
		let form_data = new FormData();
		form_data.append('upload', my_photo);
		
		//서버와의 통신
		$.ajax({
			url:'../member/updateMyPhoto',
			type:'post',
			data:form_data, //문자열이 아닌 변수로 명시했기 때문에 ''가 없음
			dataType:'json',
			contentType:false,
			processData:false,
			success:function(param){
				if(param.result == 'logout'){
					alert('로그인 후 사용하세요');
				}else if(param.result == 'success'){
					alert('프로필 사진이 수정되었습니다.');
					//교체된 이미지를 저장해서 변심 시(원상복귀 할 경우) 저장된 파일로 원상복귀 하게끔 함
					photo_path = $('.my-photo').attr('src');
					//초기화
					$('#upload').val('');
					$('#photo_choice').hide();
					$('#photo_btn').show();
				}else {
					alert('파일 전송 오류 발생');
				}
			},
			error:function(){
				alert('네트워크 오류 발생');
			}
		});
	});//end of click - 파일 전송
	
	//취소 버튼 처리
	$('#photo_reset').click(function(){
		$('.my-photo').attr('src',photo_path); //취소 버튼 click시 원래 이미지로 돌아가기
		$('#upload').val('');
		$('#photo_choice').hide();
		$('#photo_btn').show();
		
	});//end of click - 취소 버튼 처리
});

1.

let photo_path = $('.my-photo').attr('src');

my-photo의 src 속성을 가져와서 photo_path에 담기

 

2.

contentType은 보내는 데이터의 타입이다.
application/json; charset-utf-8이 흔히 쓰인다.
디폴트는 application/x-www-form-urlencoded; charset=utf-8 이다.

dataType은 서버에서 어떤 타입을 받을 것인지를 의미한다.
json, html, text 등등...
jQuery가 이것을 이용해 success나 done 함수의 파라미터로 받아 처리한다.

Ajax 요청에서 dataType 과 contentType은 뭐가 다른걸까? (velog.io)

 

Ajax 요청에서 dataType 과 contentType은 뭐가 다른걸까?

이 글은 stackoverflow 의 글을 해석한 글입니다. 출처 https://stackoverflow.com/questions/18701282/what-is-content-type-and-datatype-in-an-ajax-request/18701357다음

velog.io

 

 

 

=============================

여기까지 수행 후 사진 미리보기 후 취소 버튼 누르면 기본 이미지로 되는 것까지 되어야 함

 

 

 

 

 

 

 

Mapper에 sql문 추가 작성

MemberMapper.java

//자동 로그인
public void updateAu_id(String au_id, int mem_num);
public void selectAu_id(String au_id);
public void deleteAu_id(int mem_num);
//프로필 이미지 업데이트
@Update("UPDATE spmember_detail SET photo=#{photo},photo_name=#{photo_name} WHERE mem_num=#{mem_num}")
public void updateProfile(MemberVO member);

위 구문 복사해서 MemberService.java에도 붙여넣기 (updateProfile 어노테이션은 삭제)

--> 붙여 넣으면 Serviceimpl 에도 자동으로 에러가 나는데 unimplements 누르면 자동으로 메서드 생기면서 에러 없어짐

 

 

 

 

 

 

 

MemberServiceImpl

@Override
public void updateProfile(MemberVO member) {
    memberMapper.updateProfile(member);
}

 

 

 

 

 

 

 

MemberAjaxController

/*=======================
 *     프로필 사진 업로드
 *======================= */
@RequestMapping("/member/updateMyPhoto")
@ResponseBody
public Map<String,String> processProfile(MemberVO memberVO,HttpSession session){
   Map<String,String> mapAjax = new HashMap<String,String>();

   //로그인 유무 체크 후 처리
   MemberVO user = (MemberVO)session.getAttribute("user");
   if(user==null) {
       mapAjax.put("result", "logout");
   }else {
       memberVO.setMem_num(user.getMem_num());
       memberService.updateProfile(memberVO);

       mapAjax.put("result", "success");
   }
   return mapAjax;
}

============================
restart 후 my페이지에서 사진 업로드하면

photo (null) -> (blob)
photo_name (null) -> (파일이름.jpg)

라고 오라클 변경됨 (정상 실행 됐을 때에)

=============================

MemberVO 를 보면
public void setUpload(MultipartFile upload) 라고 upload라 지정했기 때문에 반드시 이름을 upload로 지정해야함

그래서 member.profile을 보면 파일 업로드 처리 시 form_data.append('upload', my_photo) 라고 upload 이름으로 넘기고 있음

 

 

 


 

 

 

 

<db저장 후 페이지에도 보이게 출력하기>

 

 

데이터가 db에는 들어갔지만 저장 후 page에 들어가진 않음 호출하는 방법을 해볼것

++
이전에 기본 이미지 본다고 nav_mypage에 주석처리 했던 구문 정상적으로 바꾸기
ServiceImpl의 selectMember가 이미 작성이 되어 있고 이걸 사용할 거임



컨트롤러에서 호출
MemberController

/*=======================
 *      프로필 사진 출력
 *======================= */
//1. 프로필 사진 출력(로그인 전용)


//2. 프로필 사진 출력(회원번호 지정)


//3. 프로필 사진 처리를 위한 공통 코드 (1,2에 사용됨)


//4. 기본 이미지 읽기 (1,2에 사용됨)
public void getBasicProfileImage(HttpServletRequest request, Model model) {

}
}

nav_mypage의 /member/photoView가 저장된 파일을 읽어오게 함

 

 

 

 

 

src/main/java
kr.spring.util (package)
FileUtil (class)

package kr.spring.util;

import java.io.FileInputStream;
import java.io.IOException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FileUtil {
	public static byte[] getBytes(String path) {
		FileInputStream fis = null;
		byte[] readbyte = null;
		try {
			fis = new FileInputStream(path);
			readbyte = new byte[fis.available()];
			fis.read(readbyte);
		}catch(Exception e) {
			log.error(e.toString());
		}finally {
			if(fis!=null)try {fis.close();}catch(IOException e) {}
		}
		return readbyte;
	}
}

 

 

 

 

 

 

 

 

 

본래 이미지가 static안에 있지만 request.getServletContext().getRealPath를 이용해서 읽어오게 된다면

webapp에 읽어와지기 때문에 경로를 추가해야함

정리 >> (db에 올리는 것이 아닌) context경로 상에서 파일을 읽어올 때는 webapp밑에 있는걸 읽어오기 때문에 경로가 다름!!!!


webapp
image_bundle (folder) 생성하고
face.png 복사해서 저 안에 넣기

 

 

 

MemberController

/*=======================
 *      프로필 사진 출력
 *======================= */
//1. 프로필 사진 출력(로그인 전용)
@RequestMapping("/member/photoView")
public String getProfile(HttpSession session, HttpServletRequest request, Model model) {
    MemberVO user = (MemberVO)session.getAttribute("user");
    log.debug("<<프로필 사진 읽기>> : " + user);
    if(user==null) { //로그인이 되지 않은 경우
        getBasicProfileImage(request, model);
    }else { //로그인된 경우
        MemberVO memberVO = memberService.selectMember(user.getMem_num());
        viewProfile(memberVO, request, model);
    }
    return "imageView";
}


//2. 프로필 사진 출력(회원번호 지정)


//3. 프로필 사진 처리를 위한 공통 코드 (1,2에 사용됨)
public void viewProfile(MemberVO memberVO, HttpServletRequest request, Model model) {
    if(memberVO==null || memberVO.getPhoto_name()==null) {
        //업로드한 프로필 사진 정보가 없어서 기본 이미지 표시
        getBasicProfileImage(request, model);
    }else {//업로드한 이미지 읽기
        model.addAttribute("imageFile", memberVO.getPhoto());
        model.addAttribute("filename", memberVO.getPhoto_name());
    }
}


//4. 기본 이미지 읽기 (1,2에 사용됨)
public void getBasicProfileImage(HttpServletRequest request, Model model) {
    //바이트 배열로 변환해서 읽어오기
    byte[] readbyte = FileUtil.getBytes(request.getServletContext().getRealPath("/image_bundle/face.png"));
    model.addAttribute("imageFile", readbyte);
    model.addAttribute("filename", "face.png");
}

 

 

 

 

 

 

 

 

 

mbox에서 선생님이 공유해준 imageView 다운받기

src/main/java
kr.spring.view (package) 생성 후 붙여넣기

=============================

byte[] 을 읽어들여서 string으로 변환, 전송해주는 view임
그럼 이제 mypage로 가보면 기본 이미지에서 저장했던 이미지로 화면 출력됨

 

 

 


 

 

 

 

 

<header에 프로필 미리보기 추가>

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- 상단 시작 -->
<h2 class="align-center">SpringPage</h2>
<div class="align-right">
	<c:if test="${!empty user}">
	<a href="${pageContext.request.contextPath}/member/myPage">MY페이지</a>
	<img src="${pageContext.request.contextPath}/member/photoView" width="25" height="25" class="my-photo">
	</c:if>
	
	<c:if test="${!empty user && !empty user.nick_name}">
	[<span class="user_name">${user.nick_name}</span>]
	</c:if>
	<c:if test="${!empty user && empty user.nick_name}">
	[<span class="user_name">${user.id}</span>]
	</c:if>
	
	<c:if test="${!empty user}">
	<a href="${pageContext.request.contextPath}/member/logout">로그아웃</a>
	</c:if>
	
	<c:if test="${empty user}">
	<a href="${pageContext.request.contextPath}/member/registerUser">회원가입</a>
	<a href="${pageContext.request.contextPath}/member/login">로그인</a>
	</c:if>
	
	<c:if test="${empty user || user.auth != 9}">
	<a href="${pageContext.request.contextPath}/main/main">홈으로</a>
	</c:if>
	
	<c:if test="${!empty user && user.auth == 9}">
	<a href="${pageContext.request.contextPath}/main/admin">관리자</a>
	</c:if>
</div>
<!-- 상단 끝 -->

 

프로필 update 순서

자바빈 메서드 byte[] 설정 ->
Member.profile.js 미리보기 처리 ->
MemberAjaxController
Map으로 받아서 ajax통신 / jackson lib사용
->memberVO 저장 ->
service ->mapper.java

 

 

 

 

 


 

 

<게시판 처리>

 

 

 

sql

table.sql

--게시판
create table spboard(
 board_num number not null,
 title varchar2(90) not null,
 content clob not null,
 hit number(8) default 0 not null,
 reg_date date default sysdate not null,
 modify_date date,
 ip varchar2(40) not null,
 mem_num number not null,
 constraint spboard_pk primary key (board_num),
 constraint spboard_fk foreign key (mem_num) references spmember (mem_num)
);

create sequence spboard_seq;

 

 

 

 

 

VO생성

kr.spring.board.vo (package)
BoardVO

package kr.spring.board.vo;

import java.sql.Date;

import javax.validation.constraints.NotBlank;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@ToString
@Setter
@Getter
public class BoardVO {
	private int board_num;
	@NotBlank
	private String title;
	@NotBlank
	private String content;
	private int hit;
	private Date reg_date;
	private Date modify_date;
	private String ip;
	private int mem_num; //작성자
	
	private String id;
	private String nick_name;
	
	private int re_cnt; //댓글 개수
	private int fav_cnt; //좋아요 개수
	
}

 

 

 

 

 

 

 

validation.properties

#게시판
NotBlank.title=제목은 필수
NotBlank.content=내용은 필수

 

 

 

 

 

 

 

kr.spring.board.dao (package)
BoardMapper (interface)

package kr.spring.board.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Mapper;

import kr.spring.board.vo.BoardVO;

@Mapper
public interface BoardMapper {
	//부모글
	public List<BoardVO> selectList(Map<String,Object> map);
	public int selectRowCount(Map<String,Object> map);
	public void insertBoard(BoardVO board);
	public BoardVO selectBoard(int board_num); //한 건의 레코드 반환
	public void updateHit(int board_num);
	public void updateBoard(BoardVO board);
	public void deleteBoard(int board_num);
	//좋아요
	//댓글
}

 

 

 

 

 

 

kr.spring.board.service
BoardService (interface)

package kr.spring.board.service;

import java.util.List;
import java.util.Map;

import kr.spring.board.vo.BoardVO;

public interface BoardService {
	//부모글
	public List<BoardVO> selectList(Map<String,Object> map);
	public int selectRowCount(Map<String,Object> map);
	public void insertBoard(BoardVO board);
	public BoardVO selectBoard(int board_num); //한 건의 레코드 반환
	public void updateHit(int board_num);
	public void updateBoard(BoardVO board);
	public void deleteBoard(int board_num);
	//좋아요
	//댓글
}

 

 

 

 

 

 

 

kr.spring.board.service
BoardServiceImpl (class)

package kr.spring.board.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import kr.spring.board.dao.BoardMapper;
import kr.spring.board.vo.BoardVO;

@Service
@Transactional
public class BoardServiceImpl implements BoardService{
	@Autowired
	private BoardMapper boardMapper;
	
	@Override
	public List<BoardVO> selectList(Map<String, Object> map) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int selectRowCount(Map<String, Object> map) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void insertBoard(BoardVO board) {
		// TODO Auto-generated method stub
	}

	@Override
	public BoardVO selectBoard(int board_num) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void updateHit(int board_num) {
		// TODO Auto-generated method stub
	}

	@Override
	public void updateBoard(BoardVO board) {
		// TODO Auto-generated method stub
	}

	@Override
	public void deleteBoard(int board_num) {
		// TODO Auto-generated method stub
	}

}

 

 

 

 

 

 

 

 

kr.spring.board.controller
BoardController

package kr.spring.board.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import kr.spring.board.service.BoardService;
import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
public class BoardController {
	@Autowired
	private BoardService boardService;
	
	/*===========================
	 * 게시판 글 목록
	 * ==========================*/
	@RequestMapping("/board/list")
	public ModelAndView process(@RequestParam(value="pageNum",defaultValue="1") int currentPage, String keyfield, String keyword) {
		Map<String,Object> map = new HashMap<String,Object>();
		
		ModelAndView mav = new ModelAndView();
		
		return mav;
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형
댓글수0