카테고리 없음

0304 오후수업

logloglog 2021. 3. 4. 17:31

main.js

이 함수를 호출하는쪽은 다 변경이되어야함

 

메인데코레이터jsp

메뉴를 뿌려주는부분

 

	@RequestMapping("/home")
	public String main() {
		String url="/common/home";
		return url;
	}

 

home.html 가져오기

 

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>

<body class="hold-transition sidebar-mini">



  <!-- Content Wrapper. Contains page content -->
  <div >
    <!-- 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">Starter Page</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">Starter Page</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-sm-4">
          	
       		<div class="card card-success">
              <div class="card-header">
                <h3 class="card-title">Collapsable</h3>
                <div class="card-tools">
                  <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i>
                  </button>
                </div>
                <!-- /.card-tools -->
              </div>
              <!-- /.card-header -->
              <div class="card-body">
                The body of the card
              </div>
              <!-- /.card-body -->
            </div>
          </div>
          <div class="col-sm-4">
          	
       		<div class="card card-primary">
              <div class="card-header">
                <h3 class="card-title">Collapsable</h3>
                <div class="card-tools">
                  <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i>
                  </button>
                </div>
                <!-- /.card-tools -->
              </div>
              <!-- /.card-header -->
              <div class="card-body">
                The body of the card
              </div>
              <!-- /.card-body -->
            </div>
          </div>
          <div class="col-sm-4">
          	
       		<div class="card card-danger">
              <div class="card-header">
                <h3 class="card-title">Collapsable</h3>
                <div class="card-tools">
                  <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i>
                  </button>
                </div>
                <!-- /.card-tools -->
              </div>
              <!-- /.card-header -->
              <div class="card-body">
                The body of the card
              </div>
              <!-- /.card-body -->
            </div>
          </div>
        </div>
        <!-- /.row -->
        <div class="row">
        	<div class="col-sm-8">
	        	<div class="card card-danger">
	              <div class="card-header">
	                <h3 class="card-title">Collapsable</h3>
	                <div class="card-tools">
	                  <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i>
	                  </button>
	                </div>
	                <!-- /.card-tools -->
	              </div>
	              <!-- /.card-header -->
	              <div class="card-body">
	                The body of the card
	              </div>
	              <!-- /.card-body -->
          	  </div>
        	</div>
        	<div class="col-sm-4">
        		<div class="card card-danger">
	              <div class="card-header">
	                <h3 class="card-title">Collapsable</h3>
	                <div class="card-tools">
	                  <button type="button" class="btn btn-tool" data-card-widget="collapse">
	                  <i class="nav-icon fas fa-tachometer-alt"></i>
	                  </button>
	                </div>
	                <!-- /.card-tools -->
	              </div>
	              <!-- /.card-header -->
	              <div class="card-body">
	                The body of the card
	              </div>
	              <!-- /.card-body -->
	            </div>
        	</div>
        </div>
        
      </div><!-- /.container-fluid -->
    </div>
    <!-- /.content -->
  </div>
  <!-- /.content-wrapper -->

</body>

common/home.jsp

 

 

indexpage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>

<body>
  <div class="content-wrapper">
     	<iframe name="ifr" src="<%=request.getContextPath()%>/home.do" frameborder="0" style="width:100%;height:80vh;"></iframe>
  </div>

<!-- main  -->
<script src="<%=request.getContextPath() %>/resources/js/main/main.js"></script>

<script type="text/x-handlebars-template"  id="subMenu-list-template" >
{{#each .}}
	<li class="nav-item subMenu" >
      	<a href="javascript:goPage('{{murl}}','{{mcode}}');initPageParam();" class="nav-link">
          <i class="{{micon}}"></i>
             <p>{{mname}}</p>
        </a>
	</li>
{{/each}}
</script>

<script>
window.onload=function(){
	goPage('<%=request.getContextPath()%>{menu.murl}','${menu.mcode}');
	subMenu('${menu.mcode}'.substring(0,3)+"0000",<%=request.getContextPath()%>);
}
</script>

</body>




 

 

서브메뉴에 고페이지 유알엘에 컨텍스트패스가 들어가야하는데 서브매뉴 탬플릿이 자바스크립트로 되어있기 때문에 꼬이는중

 

템플릿에다가 주자

 

 

 

여기 디폴트 줫던거 빼기

 

커먼컨트롤러에 로그아웃 만들어야

@RequestMapping(value="/common/logout",method=RequestMethod.GET)
	public String logout(HttpSession session) {
		String url= "redirect:/";
		session.invalidate();
		return url;
	}

루트로 간다.

 

메인데코레이터

 

 

**스프링뷰리졸버는 /만 붙여도 컨텍스트패스를 붙여줌

 

	@RequestMapping(value="/common/logout",method=RequestMethod.GET)
	public String logout(HttpServletRequest request, HttpSession session) {
		String url= "redirect:/";
		session.invalidate();
		return url;
	}

 

 


회원단

멤버컨트롤러

	@Autowired
	private MemberService memberService;
	
	@RequestMapping("/main")
	public String main() {
		String url = "member/main";
		return url;
	}

회원리스트 화면부터

회원리스트에 대한 컨트롤러는 파라미터 4개받아야함. 검색정보,페이지정보 (perpagenum, searchtype, keyword)

 

이제 메인페이지를 만들자

member/main.jsp

 

 

url과 jsp page url이 동일하다???

결론은 유알엘을 안줘도 된다

어댑터 덕분에 이두개가 같다

 

해당 유알엘과 페이지 유알엘이 동일하면 굳이 줄 필요가 없다.

 

이컨트롤러가 요청되엇던 유알엘을 그대로 서블릿에게 준다 (member/main)

그럼 서블렛은 어댑터가 준 대로 뷰리졸버에게 건낸다

그래서 겟이건 포스트이건 상관없이

보여줄 화면의 포워딩 유알엘 페이지유알엘과 동일하면

페이지리턴을 생략한다

 

단 조건

우리는 클래스를 만들면서 생성자를 만든적이없는데 컴파일러가 어시스턴트해줘서 컴파이릉ㄹ 할때 기본생성자를 심어줬었음 (근데 이때 조건: 생성자가 아무것도 없을떄만 이엇음)

 

같은 맥락으로,

화면을 결정할수잇는 인자가 아무것도 없을때 핸들러 어댑터는 받았던 유알엘을 그대로 섯블릿에게 보낸다.

 

화면결정인자가 뭐가잇을까? >>>RESPONSE

 

리퀘스트는 화면결정인자가 아니다. 사용자에게 뭔가가 나간다는것은 결국 리스펀스

http서블렛리스펀스를 언급하면

어댑터의 오지랖이 사라진다.

즉 내부적으로 화면을 돌리겠다고 생각하기떄문에 . 뷰리턴을 아무것도하지않음

리스펀스로 뭔가 하려면 그건 스프링 MVC  와 관계없이 나가게해주겟다고 한거임

리스펀스로 하던거 그대로 해라~!

 

 


리스트화면으로 넘어가자

 

4가지 파라미터를 받아야함 (서치타입, 키워드...)

컨트롤러 메서드의 파라미터의 변수명만 맞춰주면 받을수잇다

int page int perpagenum string keyword String searchtype이라 하면 받아준다

이걸 받아서 우리가 결국 만들게 서치크리테리아임

그걸 또 셋 펄페이지넘 셋 키워드.... 해야함

 

생각해보니 서치크리테리아 이름도 똑같음

그럼 한방에가자

파라미터에 (서치크리테리아)주면 끝남

 

 

 

String integer 같은 애들을 단일 레퍼런스라고하면

서치크리테리아는 안에 프로퍼티가많으므로 집합레퍼런스라고 치고

 

단일 레퍼런스가 오면 셋메서드호출안하고 직접 할당

집합레퍼런스가 오면 셋메서드를 파라미터 이름으로 유추하여  셋메서드를 만들어서 꺼내기시작함

그래서 그게 잇으면 인보크하는거임

 

즉 이 안에잇는 변수명을 파라미터 이름이랑 맞춰라

이걸로 파라미터 끝

	@RequestMapping("/list")
	public ModelAndView list(SearchCriteria cri, ModelAndView mnv) throws SQLException {
		String url = "member/list";
		Map<String,Object> dataMap = memberService.getSearchMemberList(cri);
		
		mnv.addAllObjects(dataMap);
		mnv.setViewName(url);
		
		return mnv;
	}

이 맵을 리졸버가 맵에 들어있는 키 이름으로 리퀘스트에 심어줌

 

즉 이걸 jsp에서 꺼내려면 멤버리스트로, 페이지메이커로 꺼낸다.

 

list.jsp가져와보자

리퀘스트레 페이지메이커, 멤버리스트가 바로들어가잇다는것만 알고잇음 우리는

 

<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<c:set var="cri" value="${pageMaker.cri }" /> 
 
<body>
	    <!-- Main content -->
    	<section class="content">
    	  <div class="card">    		
    	  	<div class="card-header with-border">
    	  		<button type="button" class="btn btn-primary" 	onclick="OpenWindow('registForm.do','회원등록',800,700);" >회원등록</button>
    	  		<div id="keyword" class="card-tools" style="width:550px;">
				  <div class="input-group row">	
				 	 <!-- sort num -->
				 	 <select class="form-control col-md-3" name="perPageNum" id="perPageNum" onchange="searchList_go(${cri.page });">
				  		<option value="10" >정렬개수</option>
				  		<option value="2" ${cri.perPageNum == 2 ? 'selected':''}>2개씩</option>
				  		<option value="3" ${cri.perPageNum == 3 ? 'selected':''}>3개씩</option>
				  		<option value="5" ${cri.perPageNum == 5 ? 'selected':''}>5개씩</option>
				  	</select>
				  <!-- search bar -->
				 	<select class="form-control col-md-3" name="searchType" id="searchType">
						<option value=""  ${cri.searchType eq '' ? 'selected':''}>검색구분</option>
						<option value="i"  ${cri.searchType eq 'i' ? 'selected':''}>아이디</option>
						<option value="p"  ${cri.searchType eq 'p' ? 'selected':''}>전화번호</option>
						<option value="e"  ${cri.searchType eq 'e' ? 'selected':''}>이메일</option>
					</select>			 										
					<input  class="form-control" type="text" name="keyword" 
					placeholder="검색어를 입력하세요." value="${cri.keyword }"/>
					<span class="input-group-append">
						<button class="btn btn-primary" type="button" 
						id="searchBtn" data-card-widget="search" onclick="searchList_go(1);">
							<i class="fa fa-fw fa-search"></i>
						</button>
					</span>
					<!-- end : search bar -->
				  </div>
				 </div>    	  		
    	  	</div>	  
    		<div class="card-body" style="text-align:center;">
    		  <div class="row">
	             <div class="col-sm-12">	
		    		<table class="table table-bordered">
		    			<tr>
		                	<th>아이디</th>
		                	<th>패스워드</th>
		                	<th>이메일</th>
		                	<th>전화번호</th>
		                	<th>등록날짜</th> <!-- yyyy-MM-dd  -->
		               	</tr>
		              
		              	
		              	<c:forEach items="${memberList }" var="member" >
		              	
		              	<tr onclick="OpenWindow('detail.do?id=${member.id}','','800','900');" style="cursor:pointer;">
		              		<td>${member.id }</td>
		              		<td>${member.pwd }</td>
		              		<td>${member.email }</td>
		              		<td>${member.phone }</td>
		              		<td><fmt:formatDate value="${member.regDate }" pattern="yyyy-MM-dd" /></td>
		              	</tr>
		              	
		              	</c:forEach>
		              	
		              	
		    		</table>
    		   </div> <!-- col-sm-12 -->
    		 </div> <!-- row -->
    		</div> <!-- card-body -->
    		<div class="card-footer">
  				<%@ include file="/WEB-INF/views/common/pagination.jsp" %>
    		</div> <!-- card-footer -->
          </div> <!-- card  -->
    	</section>	

</body>








 

 

회원등록화면이 registform.do니까

 

 

 

 

 

 

 

 


회원등록에서

사진업로드할건데

파일이 ㅇ넘어올텐데

원래는

멀티파트http리퀘스트파서MultipartHttpServletRequestParser를이용해서 아이템리스트받은바음

파일업로더리졸버FileUploadResolver에 아이템파일을 주면 저장한다음 어태치브이오리스트를 줘서

파일이름 뺀다음 리턴해서 에이젝스로 던졌엇음

 

저 위에 색칠한거 이제 안만듦

 

대신에 파일업로드자르가 필요함

commons file upload >> pom.xml에 디펜던시추가

멀티파트리졸버는 우리가 안만들고, 잇는거 그냥 단다

 

 

저장경로와 파일이름을 정한다음

멀티.트랜스퍼투 하면 저장하고 끝남

 

우리가햇던 멀티파트파서 사라짐. 저장은 경로랑파일정해서 트랜스퍼투하면 저장됨

 

시나리오 기억하기

: 회원단에서 파일업로드 어케햇냐면 폼태그 하나만들엇음 (업로드전용으로) 업로드버튼 누르면 따로만든 인풋파일의 인풋태그가 작동되어서 인풋태그에 파일이 들어옴 에이젝스로 이걸 던졋음. 사용자가 이미지를 변경해서 재차업로드됏다면 .. 다음업로드할때는 그전에게 이전파일로 들어옴.

 

파일선택하는 버튼은 인풋태그를 조작하는거고 업로드는 그 폼태그를 에이젝스로 폼데이터로 던지는 놈임

그 유알엘이 member picture upload

이걸 컨트롤러가 (픽쳐업로드핸들러보기...) 받음

 

 

이게 스프링에서는 멀티파트리졸버임

 

이 형태가 아니라

 

이걸로 뽑아줌. 멀티파트리졸버가

 

어댑터는 그걸 그냥 받는거뿐임

 

3가지 기억

 

1. 폼태그는 멀티파트인거 2. 커먼즈자르넣어야하는것도 변함없음

3. 그걸 사용하는 멀티파트리졸버를 서블릿에게 달아준다

 

어댑터가 받아서 멀티파트파일로 컨트롤러에게 넘겨준다


일단 자르넣는게 우선임

   <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>${commons.fileupload-version}</version>
		</dependency>

 

 

서블릿ㅌ컨텍스트

 

기본네임스페이스가 beans이기떄문에 beans를 붙이지않아도됏던것
빈즈가 기본네입스페이스가 아니기떄문에 빈 등록시 vbeans:붙여야함

서블렛컨텍스트

<beans:bean id="multipartResolver"
				class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
				p:defaultEncoding="utf-8"
				/>

 

멤버컨트롤러

	@RequestMapping(value="/picture",method=RequestMethod.POST)
	   @ResponseBody
	   public ResponseEntity<String> picture(@RequestParam("pictureFile") MultipartFile multi, String oldPicture) throws Exception{
	      ResponseEntity<String> entity = null;
	      return entity;
	   }
	

파일명던질거니까 스트링

 

저 픽쳐는 저장하고 올드픽쳐는 삭제

저장경로는 프로퍼티에서 가져올거임

이놈들도 빈등록함

 

어플리케이션컨텍스트

<!-- boardImgPath -->
	<bean id ="imgPath" class="java.lang.String">
		<constructor-arg value="${summernote.img}"/>
	</bean>	
	
<!-- member.picture -->
	<bean id="picturePath" class="java.lang.String">
		<constructor-arg value="${member.picture.upload}"/>
	</bean>	
	
<!-- file upload -->
	<bean id="fileUploadPath" class="java.lang.String">
		<constructor-arg value="${attach.upload}"/>
	</bean>

우리 지난번에 업로드패스.properties만들엇는데 그걸 프로퍼티폴더에 넣으면 다 읽을거임 (루트컨텍스트에해놧기떄문)

거기에잇는 키 이름 으로 가져올수잇다는 얘기임

 

 

 

저렇게 키 주면 루트컨텍스트에서 읽어내서 밸류를 가져올거임

 

빈등록되어잇으니까 autowire로 땡길수잇다.

근디

<!-- boardImgPath -->
	<bean id ="imgPath" class="java.lang.String">
		<constructor-arg value="${summernote.img}"/>
	</bean>	
	
<!-- member.picture -->
	<bean id="picturePath" class="java.lang.String">
		<constructor-arg value="${member.picture.upload}"/>
	</bean>	
	
<!-- file upload -->
	<bean id="fileUploadPath" class="java.lang.String">
		<constructor-arg value="${attach.upload}"/>
	</bean>
		

타입이 다 같다.. 즉 autowired로 땡기면 여러개가 오기떄문에 안됨

 

이걸로 세이브경로떙길거임

 

빈등록한 빈의 이름으로 떙길수잇는 애노테이션이 잇다 >> @Resource (얘는 이름으로 땡기고 타입비교하지않는다)

 

~지금은 레스트방식으로 ㅂ파일을 하나받는거만 하고잇음~

 

이미지 업로드는 할게많음 > 중복파일 해결, 기존파일 지우고 저장한 파일 추출해서 다시줘야함

이걸 여기다적으면 많으니까 하나으 ㅣ메서드형태로 만들자

 

 

 

private String savePicture(String oldPicture, MultipartFile multi) throws Exception{
		String fileName = null;
		
		/*파일유무확인*/
		if(!(multi==null || multi.isEmpty() || multi.getSize() > 1024*1024*5)) {
			/*파일저장폴더설정*/
			String uploadPath = picturePath;
			fileName = UUID.randomUUID().toString().replace("-", "") + ".jpg";
			File storeFile = new File(uploadPath,fileName);
			
			storeFile.mkdirs();
			
			//local HDD에 저장
			multi.transferTo(storeFile);

			if(!oldPicture.isEmpty()) {
				File oldFile = new File(uploadPath,oldPicture);
				if(oldFile.exists()) {
					oldFile.delete();
				}
			}
		}
		return fileName;
	}

메서드 하나 추가

 

컨트롤러가 주는 올드파일과 멀티파일받아서

파일잇는지 확인해서 이슴녀 파일명 만듦

uuid에 하이픈잇으니 패고 .jpg 붙여주고

mkdirs 매서드 자체가 디렉토리 잇으면 안만들고 없을때만만들기떄문에 if안해두됨

 

이거에 안걸리면 파일네임이 널임

즉 멀티파트가 널이거나, 멀티가 파일이없거나 크기가작거나 하면 널이온다

 

그래서 널이면(할당연산자가 비교보다 먼저라 리절트가 널인지비교하는거임!)

암튼 그래서 널이라면

bad request를 응답코드로 내보낼거임

그게아니면 파일명 온거니까

 status 를 OK 로 만들고 OK로 나갈거임

@RequestMapping(value="/picture",method=RequestMethod.POST)
	   @ResponseBody
	   public ResponseEntity<String> picture(@RequestParam("pictureFile") MultipartFile multi, String oldPicture) throws Exception{
	      ResponseEntity<String> entity = null;
	      
	      String result="";
	      HttpStatus status = null;
	      
	      /*파일저장확인*/
	      if((result = savePicture(oldPicture, multi))==null) {
	    	  result = "업로드실패햇습니다.";
	    	  status = HttpStatus.BAD_REQUEST;
	      }else {
	    	  status = HttpStatus.OK;
	      }
	      
	      entity = new ResponseEntity<String>(result,status);
	      
	      return entity;
	   }
	

 

테스트는 폴더를 봐야함

 

저기로 들어와야하는데 안됨 수정해야댐

윈도우 펑션안에 펑션이잇으면 선언인안되는데

 

 

regist_picture

수정

function fileChange_go(){
	//alert('file change');
	
	var fileInput = $('input#inputFile'); 

추가

리플레이스올

그냥 복붙하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>

function fileChange_go(){
	//alert('file change');
	
	var fileInput = $('input#inputFile'); 
	
	//업로드 확인변수 초기화
	$('input[name="checkUpload"]').val(0);
	
	var fileFormat=
		fileInput.value.substr(fileInput.value.lastIndexOf(".")+1).toUpperCase();
		
	//이미지 확장자 jpg 확인
	if(!(fileFormat=="JPG" || fileFormat=="JPEG")){
		alert("이미지는 jpg/jpeg 형식만 가능합니다.");
		fileInput.val("");		
		return;
	} 
	//이미지 파일 용량 체크
	if(fileInput.files[0].size>1024*1024*1){
		alert("사진 용량은 1MB 이하만 가능합니다.");
		return;
	};
	
	document.getElementById('inputFileName').value=fileInput.files[0].name;
	
	if (fileInput.files && fileInput.files[0]) {
		var reader = new FileReader();
		 reader.onload = function (e) {
			  $('div#pictureView')
	        	.css({'background-image':'url('+e.target.result+')',
					  'background-position':'center',
					  'background-size':'cover',
					  'background-repeat':'no-repeat'
	        		});
		  }
		reader.readAsDataURL(fileInput.files[0]);
		
	}
	
}

function upload_go(){
	//alert("upload btn click");
	
	if($('input[name="pictureFile"]').val()==""){
		alert("사진을 선택하세요.");
		$('input[name="pictureFile"]').click();
		return;
	};	
	
	//form 태그 양식을 객체화	
	var form = new FormData($('form[role="imageForm"]')[0]);
	
	$.ajax({
		url:"<%=request.getContextPath()%>/member/picture.do",
		data:form,
		type:'post',
		processData:false,
		contentType:false,
		success:function(data){
			//업로드 확인변수 세팅
			$('input[name="checkUpload"]').val(1);
			
			//저장된 파일명 저장.
			$('input#oldFile').val(data); // 변경시 삭제될 파일명
			$('form[role="form"]  input[name="picture"]').val(data);
			
			alert("사진이 업로드 되었습니다.");
		},
		error:function(error){
			alert("현재 사진 업로드가 불가합니다.\n 관리자에게 연락바랍니다.");
		}
	});
}
	

 

regist.jsp

window onload function 지우기

 

regist.jsp

오리지날 자바스크립트 객체를 제이쿼리에서뽑아내려면 [0] 줘야함

그래서 regist_picture 최종

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>

function fileChange_go(){
	//alert('file change');

	var fileInput = $('input#inputFile');

	//업로드 확인변수 초기화
	$('input[name="checkUpload"]').val(0);

	var fileFormat=
		fileInput[0].value.substr(fileInput[0].value.lastIndexOf(".")+1).toUpperCase();

	//이미지 확장자 jpg 확인
	if(!(fileFormat=="JPG" || fileFormat=="JPEG")){
		alert("이미지는 jpg/jpeg 형식만 가능합니다.");
		fileInput.val("");		
		return;
	} 
	//이미지 파일 용량 체크
	if(fileInput[0].files[0].size>1024*1024*1){
		alert("사진 용량은 1MB 이하만 가능합니다.");
		return;
	};

	document.getElementById('inputFileName').value=fileInput[0].files[0].name;

	if (fileInput[0].files && fileInput[0].files[0]) {
		var reader = new FileReader();
		 reader.onload = function (e) {
			  $('div#pictureView')
	        	.css({'background-image':'url('+e.target.result+')',
					  'background-position':'center',
					  'background-size':'cover',
					  'background-repeat':'no-repeat'
	        		});
		  }
		reader.readAsDataURL(fileInput[0].files[0]);

	}

}

function upload_go(){
	//alert("upload btn click");

	if($('input[name="pictureFile"]').val()==""){
		alert("사진을 선택하세요.");
		$('input[name="pictureFile"]').click();
		return;
	};	

	//form 태그 양식을 객체화	
	var form = new FormData($('form[role="imageForm"]')[0]);

	$.ajax({
		url:"<%=request.getContextPath()%>/member/picture.do",
		data:form,
		type:'post',
		processData:false,
		contentType:false,
		success:function(data){
			//업로드 확인변수 세팅
			$('input[name="checkUpload"]').val(1);

			//저장된 파일명 저장.
			$('input#oldFile').val(data); // 변경시 삭제될 파일명
			$('form[role="form"]  input[name="picture"]').val(data);

			alert("사진이 업로드 되었습니다.");
		},
		error:function(error){
			alert("현재 사진 업로드가 불가합니다.\n 관리자에게 연락바랍니다.");
		}
	});
}

 

 

 


이미지내보내기 ( 로그인 한 사용자의 이미지가 나오게)

화면이 아니기떄문에 responseBOdy 붙이고

해당 파일 읽어내서 내보내면 되기떄문에 레스트방식

레스펀트앤티티의 객체를 만들고 

이미지 경로는 이미 만들어놓은것 this.picturePath (아까 빈등록해서 받은 이미지경로)

 

읽어내면서 내보낼건데, 아웃풋스트림쓰지않음. 대신 IOUtils를 쓸거임 이놈을 이용해서 인풋스트림할당해주면

얘가 읽어내면서 빼내줌

응답코드 CREATED 는 200이고

INTERNAL 서버 에러는 500임

 

@RequestMapping("/getPicture")
	@ResponseBody
	public ResponseEntity<byte[]> getPicture(String picture) throws Exception{
		InputStream in = null;
		ResponseEntity<byte[]> entity = null;
		String imgPath = this.picturePath;
		try {
			//in=new FileInputStream(imgPath+File.separator+picture);
			in = new FileInputStream(new File(imgPath,picture));
			
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in),HttpStatus.CREATED);
		}catch (IOException e) {
			e.printStackTrace();
			entity = new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
		}finally {
			in.close();
		}
		return entity;
	}

레지스트 할떄 등록시에는 파일명을 유지안해줫음 근디 수정할떄는 파일명을 줫엇음

즉 수정화면에서변경되는 사진은 파일명을 ㅇ유지해줫엇음

지금 한글파일명이 들어올떄 꺠지는 문제가잇음

 

파일명을 받는 컨트롤러에서 반드시 해줘야하는것

두가지

1. 컨트롤러에서 할수잇는건,  (멀티파트의 파일로 올떄)

이놈을 줘서 파일명이 넘어올떄 깨지지않도록

 

2. 유알엘에 파라미터가 올떄 한글이 꺠지는데, 이건 서버의 서버.xml임

 

 

메인 화면에서 로그인 이미지느 유알엘로 요청함

이미지태그의 src의 유알엘로 온다. 이건 꺠지는거랑 상관없엇던듯??


아이디 중복쳍크

아이디가 넘어온다

 

	@RequestMapping("/idCheck")
	@ResponseBody
	public ResponseEntity<String> idCheck(String id) throws Exception{
		ResponseEntity<String> entity = null;
		//3단계로 나뉜다
		try {
			MemberVO member = memberService.getMember(id);
		
			if(member!=null) {
			//1.중복인경우
				entity = new ResponseEntity<String>("duplicated",HttpStatus.OK);
			}else {
			//2.사용가능한 아이디
				entity = new ResponseEntity<String>("",HttpStatus.OK);
			}
		}catch (SQLException e) {
			//3. 에러인경우 500을 내보내겟다
			entity = new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
		}
		return entity;
	}


등록은 

멤버VO만 옴 (파일은 이미 업로드햇으니까)

그걸 받아서 서비스호출하면됨

 

원래는 겟파라미터 셋메서드에 의지햇지만

이제 파라미터에 멤버vo만 넣으면다 받아준다 그걸 서비스에만 인가하면 된다

 

회원등록의 registcontroller는

결정인자인 레스펀스 잇음. 이거떄문에 행들러 어댑터는 보이드라고 하더라도 유알엘을 페이지 이름으로 던지지않음.

즉 리스펀스를 파라미터로 받으면 그걸로 어떻게든 화면전환을 시켜야됨 (뷰리졸버가 작동을 안하기떄문에)

그래서 포워드도 안되고, 직접 리다이렉트를 하던지 이렇게  스크립트를 내보내야 하는거임

 

멤버VO를 받으려고 햇는데 왜 받지않으까?

이상하게 받아져서 못!받은거임 이유는>?

 

phone의 인풋태그 3개라서 배열인데 멤버vo 가 되면 ㄷ맨 앞 010만 들어옴

근데 멤버테이블은 컬럼은 1개 스트링 단일

그래서 맴버vo로 못받음

 

이런일이 많다

화면은 사용자위주이기떄문에 우리가생각한 디비테이블의 형태와 좀 다를수잇음

 

또다른 예)

수정할떄도 픽쳐의 파일 인풋태그가 폼태그에 박혀잇는데, 그 파라미터 인풋태그의 이름이 픽쳐인데 그걸 멤버브이오로 받는다? 안됨 이름은 같지만 File, String이기떄문에 400나옴

 

안맞음... 즉

화면에서 오는것을 VO로 받는거가 무리임

디비는 varchar아니면 number밖에없음!!!!

 

풀캘린더같은 json데이터? 랑 VO랑 형태가 같음? 같지않다!!

 

그래서 항상 매핑해주는 애가 필요함

 

사용자가 보내주는 파라미터 데이터를 VO에 맞게 변환해주고

그반대로 VO를 사용자가 볼수잇는 데이터로 바꿔주는 변환해주는놈이 필요함

 

매핑해주는, 중간다리역할 (마샬링 언마샬링) 그 중에서도 사용자의 요청을 VO로 변환용도로 만든 객체를

커맨드객체라고 함

 

사용자가 보낸 데이터를 받기위한 객체 : 커맨드 객체

왜 커맨드로 받아야함? VO랑 안맞기때문에

결론:

얘가 최대한 memberVO로 바꿔줌