JqGrid를 이용해서 회원정보를 CRUD를 했다

날짜컬럼을 update하면 sqlException오류가 발생했다 

날짜컬럼에 YYYY-mm-dd로 입력하면 db까지 같은 형식으로 저장이 되는데

client side에서 보면 mm/dd/YYYY로 변환이 된다

날짜 형식이 달라서 update가 되지 않는 것이다

 

formatter속성으로 데이터를 조작해도 날짜 형식이 변하지 않았다

구글링을 했더니 server side에서 데이터를 조작하던지 custom formatter로 설정하라는 의견이 많았다

date custom formatter를 사용했지만 변수가 많았고 어려웠다

그래서 server side에서 데이터를 변환해보았다

 

crud가 잘된다

2019/07/18 - [웹/JAVA] - Try Catch문으로 오류잡기

 

Try Catch문으로 오류잡기

포워딩(전송)을 하게되면 오류가 발생할 수 있는데 이 오류를 두 가지로 나눌 수 있다. 컴파일오류와 실행오류이다. 컴파일오류는 오타를 쳤을때고 Java에서 알려준다. 실행오류는 예를 들어 무한 for문이다. 내가..

golddigger.tistory.com

 

 

 

실무에서는 syso 사용을 안한다. syso을 개발서버나 다른서버에 올리면 안된다. 굉장히 속도가 느리기 때문이다. 

그래서 개인 개발용으로만 사용하는 것이 좋다


Logger를 써야한다. 얘는 한줄만 있어야 한다. 
1. log.info( ); 
2. log.debug( );  
시간과 무엇으로 그리고 어디에서 찍혔는지 콘솔에 찍힌다. 

package egovframework.example.welcomeWeb.web;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import egovframework.example.welcomeWeb.service.WelcomeWebService;
import egovframework.rte.psl.dataaccess.util.EgovMap;

@Controller
public class WelcomeWebController { 
	
	private final Logger log = LoggerFactory.getLogger(getClass());
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) {
		
		try {
			String nulls = null;
			
			System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
			for (int i = 0; i < welcomeWebList.size(); i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size()+2; i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (ArrayIndexOutOfBoundsException ae) {
			//System.out.println(ae + "배열의 길이를 확인해!");
			
			log.info(ae + "배열의 길이를 확인해!");
		} catch (NullPointerException ne) {
			//System.out.println(ne + "null있다.");
			
			log.info(ne + "null있다.");
		} catch (Exception e) {
			//System.out.println(e + "그 외 모든 오류들");
			
			log.debug(e + "그 외 모든 오류들");
		} finally {
			//System.out.println("welcomeWeb Controller에서 오류");
			//System.out.println("오류가 나던 안 나던 출력");
			log.debug("welcomeWeb Controller에서 오류");
			log.debug("오류가 나던 안 나던 출력");
		}
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

 

 

++로그레벨 보는 법 
로그의 레벨을 설정한다고 한다. 왼쪽에서 오른쪽으로 읽는다. 

로그레벨

 

 

로그는 log4j2.xml에서 설정한다. 

egovframework를 사용하고 있기 때문에 여기에 설정한다.

 

 

test.log위치를 찾아서 log4j2.xml에 설정해준다.

 

프로그램을 실행시키면 콘솔창과 test.log에 잘 찍혀있는 것을 볼 수 있다.

 

syso하든 log를 찍든 그 목적은 파일을 떨구기 위해서다. 오류를 찾기보다 파일로 기록을 남기기 위해서다. 

책임을 떠맡기 싫어서 파일로 남겨둔다. 그래서 사용자가 로그인하거나 로그아웃할때 사용한다.

log는 데일리로 보관한다. 폴더명이 날짜별로 떨궈진다.

 

 

 

 

 

 

 

출처  :  한큐에 자바 수강내용 

포워딩(전송)을 하게되면 오류가 발생할 수 있는데 이 오류를 두 가지로 나눌 수 있다. 
컴파일오류와 실행오류이다. 
컴파일오류는 오타를 쳤을때고 Java에서 알려준다. 

실행오류는 예를 들어 무한 for문이다. 내가 생각한 결과물과 다른 결과물이 나올때다. 

서버는 잘뜨나 실행이 되지 않는다.

 

 

다루어볼 것은 실행오류에 대한 처리이다.
오류는 시스템 오류와 예외가 있다. 
시스템 오류는 잡을 수 없다.

예외는 내가 생각한 거와 다른 결과물로 프로그래밍으로 제어(제거)할 수가 있다.

 

모든 오류의 부모는 Throwable이다.
우리가 제어 할 수 있는 예외의 부모는 Exception이고, 
우리가 제어할 수 없는 시스템 오류의 부모는 error이다.


 



실무에서 사용하는 ExceptionHandling이다.

Exception오류는 콘솔에 안 뜬다. 왜냐하면 자바컴파일러는 오류로 생각하지 않기 때문이다. 

구조

실행오류예외처리 (RuntimeException)
try catch문을 사용해서 콘솔에 오류가 뜨게 만든다. 
try catch는 try구문 안에서 RuntimeException같은 종류의 오류가 발생하면 무조건 catch문을 타게된다. 


++실무에서 운영서버나 test서버에 프로젝트를 올리게 되면 Java파일을 올리는 것이 아니라 class파일을 올리게 된다. 
오류가 나게 되면 의지할 수 있는 곳은 콘솔 밖에 없다. 그러면 콘솔과 내 로컬 서버를 비교하면서 오류를 찾게 된다. 
그렇기 때문에 어떠한 오류가 났는지 확인 하도록 값을 같이 찍어준다.

 

@Controller
public class WelcomeWebController { 
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) {
		
		try {
			//String nulls = null;
			
			//System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
            //여기서 오류냄
			for (int i = 0; i < welcomeWebList.size()+2; i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size(); i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (Exception e) {
			System.out.println(e + "그 외 모든 오류들");
		} 
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

 

 


 



보통 array오류와 nullpoint오류가 많이 난다. 팀프로젝트에서는 test서버에서는 확인하기 힘들어서 꼭 예외 처리해준다.

일단, try문에 String 변수에다가 null을 넣어준다.

@Controller
public class WelcomeWebController { 
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) {
		
		try {
			String nulls = null;
			
			System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
			for (int i = 0; i < welcomeWebList.size(); i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size()+2; i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println(ae + "배열의 길이를 확인해!");
		} catch (NullPointerException ne) {
			System.out.println(ne + "null있다.");		
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

변수를 참조해서 실행하는데 우리가 변수에 null을 했기 때문에 참조할 수 없다. 그래서 콘솔에 nullpoint오류가 난다.

 

 


 


여러 오류가 발생한다면, 앞에 오류가 나오면 그 뒤에 오류는 안나온다. 

그래서 무슨 오류가 나오는지 여러 오류처리를 해야한다.
어디 controller에서 나온 오류인지 확인할 수 있도록 controller명도 같이 찍어준다.

@Controller
public class WelcomeWebController { 
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) throws Exception{
		
		try {
			String nulls = null;
			
			System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
			for (int i = 0; i < welcomeWebList.size(); i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size()+2; i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println(ae + "배열의 길이를 확인해!");
			
			System.out.println("welcomeWeb Controller에서 오류");
		} catch (NullPointerException ne) {
			System.out.println(ne + "null있다.");
			
			System.out.println("welcomeWeb Controller에서 오류");
		} 
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

 

 


 

 

오류가 나던 안 나던 무조건 타게 만드는 메서드는 finally이다. try catch문에서만 실행이 된다. 

@Controller
public class WelcomeWebController { 
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) throws Exception{
		
		try {
			String nulls = null;
			
			System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
			for (int i = 0; i < welcomeWebList.size(); i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size()+2; i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println(ae + "배열의 길이를 확인해!");
		} catch (NullPointerException ne) {
			System.out.println(ne + "null있다.");
		} finally {
			System.out.println("welcomeWeb Controller에서 오류");
			
			System.out.println("오류가 나던 안 나던 출력");
		}
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

 

 


 


모든 실행오류를 적어줄 수 없지만 어떤 오류인지 알수 없기 때문에 최상위 Exception를 적어준다. 
이 최상위를 위에 적어주면 나머지 오류는 실행되지 않기 때문에 최상위 Exception을 맨 아래에 넣는다.

이 오류는 꼭 있어야 하는 처리문이다.

@Controller
public class WelcomeWebController { 
	
	@Resource
	private WelcomeWebService welcomeWebService;

	@RequestMapping(value = "/welcomeWeb.do")
	public String welcomeWeb(ModelMap model) throws Exception{
		
		try {
			String nulls = null;
			
			System.out.println(nulls.toString());
			
			List<EgovMap> welcomeWebList = welcomeWebService.selectWelcomeWebServiceList(); 
			System.out.println(welcomeWebList);
			
			//List를 Map에 담아 출력해보기
			HashMap<String, Object> exceptionMap = new HashMap<String, Object>();
			
			for (int i = 0; i < welcomeWebList.size(); i++) {
				exceptionMap.put((String) welcomeWebList.get(i).get("seqNo"), welcomeWebList.get(i).getValue(1));
			}
			
			System.out.println("exceptionMap : " + exceptionMap);
			
			//담은 Map의 데이터를 배열로 출력해보기
			String[] arrStr = new String[exceptionMap.size()];
			
			for (int i = 0; i < exceptionMap.size()+2; i++) {
				arrStr[i] = (String) exceptionMap.get(String.valueOf(i+1));
			}
			
			System.out.println("arrStr : " + Arrays.toString(arrStr));
			
			List<EgovMap> pieChartList = welcomeWebService.selectPieChartList();
			System.out.println(pieChartList);
			
			model.addAttribute("welcomeWebList", welcomeWebList);
			model.addAttribute("pieChartList", pieChartList);
		
		} catch (ArrayIndexOutOfBoundsException ae) {
			System.out.println(ae + "배열의 길이를 확인해!");
		} catch (NullPointerException ne) {
			System.out.println(ne + "null있다.");
		} catch (Exception e) {
			System.out.println(e + "그 외 모든 오류들");
		} finally {
			System.out.println("welcomeWeb Controller에서 오류");
			
			System.out.println("오류가 나던 안 나던 출력");
		}
		
		return "welcomeWeb/welcomeWeb.tiles";
	}
}

 

 


 


try catch는 내가 책임지겠다는 것이고 throws exception는 나를 호출한 놈한테 책임을 주는 것이다. 책임회피다.
try랑 throw를 같이 적어주면 안된다.  controller에는 throw exception을 적어주지 않는 것을 추천한다. 

throw Exception의 controller에 적어주면 Java 뒷단에 책임을 지게 한다.

 

만약에 try랑 throws 둘다 안 적어주면 service에 오류가 난다.  

throws는 남이 호출한 메서드에 책임을 떠 앉게 해주기 때문이다.

 

 

 

 

 

 

 

출처  :  한큐에 자바 수강내용

2019/07/12 - [웹/Javascript] - 비동기식 JavaScript라이브러리 AJAX

 

비동기식 JavaScript라이브러리 AJAX

AJAX는 JavaScript의 라이브러리로 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자이다. JavaScript로 서버에 데이터를 요청한다. 화면(html)은 그대로 두고 데이터만 바꾸고 싶을 때 많이..

golddigger.tistory.com

 

 

 

jsonObject를 올리면 전처리가 쿼리스트링으로 바꿔준다. 

애초에 데이터를 올릴 때 jsonObject가 아닌 jsonObjectString으로 올려본다.

 

var form = {"param" : thisParam} ; 
이렇게 변수에 담고 ajax data에 문자열을 올려본다.  


JSON.stringify( )메서드가 jsonObject를 jsonObjectString로 바꾸는데 완벽한 문자열로 바꿔준다.

 

 


 

 

크롬  - network 에서 All로 열어서 확인해본다. 
error가 나오는데 인코딩이 잘못 되었기 때문이다. jsonObjectString이 더블코테이션(")을 읽지 못했기 때문이다.
왜냐하면 ajax는 아무것도 안써주면 자동으로 get방식이다. get방식은 특수문자를 읽지 못한다.

post방식으로 적어주면 error부분이 사라졌다.

 

post방식으로 바뀌면 개발자도구에 있는 Form Data(body)부분에 더블코테이션과 문자열이 적혀있다. 
Form Data는 body부분이다. 

Form data는 키를 보고 벨류가 안 넘어가고 있다. 
벨류를 받게 하려면 어떻게 할까? controller에 getParameterNames를 사용해준다.
Emumeration name = request.getParameterNames; 라고 적어주면 name으로 키를 사용해 벨류 값을 뽑을 수 있다.
그리고 while문을 통해서 키를 뽑아낸다. 마치 키를 벨류처럼 사용해준다. 

찍어보면 jsonObjetString(문자열)이 잘 나온것을 볼 수 있다. 

 


jsonObjectString을 쿼리스트링 형식인 map으로 바꿀때 gson을 사용한다.

String을 db로 가져가려면 map으로 바꿔줘야하는데 gson으로 jsonObjectString을 jsonObject(쿼리스트링)로 바꿔준다.

map의 키와 벨류를 String , Object로 설정했다. 그런데 map에서 get( )으로 꺼낸 키의 벨류타입은 Object이다. 
이 Object를 List의 String타입인 param에 넣으려고 하니까 오류가 난다.

그래서 강제로 String으로 형변환해준다. 

 

 


 

 


@ReqeustBody
여태 한 이 과정을 @Requestbody로 사용하면 된다.
@Requestbody는 body에 있는 문자열(데이터)을 그대로 가져온다. 

body기 때문에 post 방식일때만 쓸 수 있다. get방식은 헤더에 써서 문자열로 받아드릴수 없다.
이렇게 쓰게 되면 getParameterNames와 while문은 필요가 없다. 

@RequestBody를 사용했는데도 값이 이상하게 나왔다.

인코딩이 안 됐기 때문이다. 그래서 디코딩을 해준다.

인코딩이 암호화라면 디코딩은 복호화이다. 


 : 가 = 으로 바껴서 나오는데 subString메서드를 사용해서 잘라준다. 

 

 


 

 

subString을 사용하지 않으려면 ajax에서 contentType을 적어준다. 

애초에 contentType  :  "application/json", 이라고 적어준다. 
json으로 인코딩해주는 ajax메서드는 contentType이다. 

contentType하면 디코딩도 필요가 없다. 왜냐하면 애초에 jsonObject로 받기 때문이다.

contentType적어주기전
contentType 적고난 후

contentType을 적어주지 않으면 jsonObjectString이지만 적어주면 jsonObject로 받는다.

 

왜 굳이 jsonObject보다 jsonObjectString으로 보낼까? 왜냐하면 ajax는 post를 많이 쓰기 때문이다.
get방식은 데이터를 보내는데 한계가 있지만 post방식은 한계가 없다. 

그래서 jsonObject보다 jsonObjectString으로 보내는 일이 많다.

 

 

 


정리  :  post는 body로 받기 때문에 손쉽게 받으려면 @Requestbody를 쓴다. 

          jsonObjectString으로 나오기 때문에 content-Type을 쓴다. 

 

 

 

 

 

 

 

출처  :  한큐에 자바 수강내용

' > Javascript' 카테고리의 다른 글

JqGrid 서버사이드 format  (0) 2019.08.29
비동기식 JavaScript라이브러리 AJAX  (0) 2019.07.12
리터럴 방식의 배열  (0) 2019.07.08
자바스크립트 구성요소  (0) 2019.07.05
도큐먼트 레디가 동작하는 방법  (0) 2019.07.02

@ModelAttribute의 숨겨진 기능을 보겠다.

controller는 코딩이 짧을수록 좋다. controller의 본연의 기능인 주고받는 기능만 있으면 된다.

@ModelAttribute를 사용하면 코딩이 짧아진다.
추가로, 화면단에서는 도큐먼트레디 안의 양이 적을수록 좋다. 화면 몇 개를 호출하는지 알 수 있을 정도만 하면 된다.
controller는 업무당 하나를 만드는데

만약,  3개의 화면을 호출할려면 하나의 controller에 3개의 메서드를 만든다. 
하지만 @ModelAttribute를 사용하면 간단해진다. 

 

 

@ModelAttribute를 메서드 밖에 주고  알리아스(alias)를 준다. 

이 알리아스는 model.addAttribute의 키와 같다. 
@ModelAttribute에 쓰인 키에 모든 결과 값이 들어간다.  
결과는 return selectBoxService.selectParentBoxList( );로

이걸 몇 개씩 사용해서 쓰면 코딩이 엄청 짧아진다. 

 

 

@ModelAttribute controller에 있는 메서드 중에서 가장 먼저 실행이 된다.  
@RequestMapping보다 먼저 실행된다.

 

 

 

 

출처  :  한큐에 자바 수강내용

 AJAX는 JavaScript의 라이브러리로 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자이다.

JavaScript로 서버에 데이터를 요청한다.

 

화면(html)은 그대로 두고 데이터만 바꾸고 싶을 때 많이 이용한다. 대표적인 예시가 mult selectBox다. 

화면을 부분적으로만 그리고 싶을 때 사용한다. 

JSTL이 AJAX보다 빠르다. 왜냐면 화면을 그리면서 보여주기 때문이다.
JSTL는 화면을 다 그릴때 사용하고 AJAX는 부분적으로 그릴 때와 데이터를 바꾸고 싶을 때 사용한다.

 

AJAX는 대표적인 비동기 방식이다.

*동기와 비동기
동기    :  예를 들어, 사수가 부사수한테 팝업하라고 명령할 때 사수가 다 할 때까지 계속 쳐다보고 있는 것이다. 

            부사수가 일을 다해야 사수가 받아서 수행한다.
비동기 :  부사수가 일을 하고 있으면 사수는 지 할 일 하는 것이다.  비동기의 대표적언어는 node.js이다.

 

 


 

 

selectBox로 DB테이블에 where조건문을 걸어서 원하는 값을 가져와보겠다.

DB데이터이다. 

brandCd db
prdCd db
SQL
화면

첫 번째 selectBox에는 brandCd가 나오고 두 번째 selectBox에는 brandCd로 분류한 prdCd가 나온다.

JSTL과 AJAX를 적절히 사용해야한다. brandCd는 화면에 그대로 둬도 되기때문에 JSTL로 화면에 내린다.

selectBox Controller에 MVC패턴으로 데이터를 보냄
selectBox.jsp에 JSTL로 화면에 내렸다.
화면에 brandCd가 잘 나옴
개발자도구로 보면 반복문이 잘 적용됨

 

 


 

 

이제 같은 brandCd를 가지고 있는 prdCd를 두 번째 selectBox에 내린다. 

즉, brandCd를 선택한 것에 따라 prdCd가 나온다.

 

그전에, 추가로 AJAX의 기본 형태를 보면

type      -  type을 안 적어주면 기본적으로 get방식이다. 쿼리스트링형식이 화면 주소창에 나온다.

data      -  data에 적혀있는 { }중괄호는 객체다. 이 객체를 들고 가는데, 객체 안에는 문자열("a")과 value(b)가 있다. 

               이 모양을 jsonObject라고 한다.
               { }가 있고 안에 모양이 json모양이기 때문에 jsonObject라고 한다.

success  -  controller, service, serviceImpl, mapper, DB까지 MVC로 뒤져서 나온 데이터를 갖고 와서 

              모델로 화면에 떨궈지는데 success에 떨궈진다. 최종 도착지인 셈이다.

 

prdCd구하는 로직

 여기서 change( )는 내가 클릭한 selectBox로 클릭할때마다 brandCd가 바뀐다.

*AJAX 전처리
jsonObject형태로 controller에 보내면 AJAX전처리가 jsonObject만 쿼리스트링형식으로 변형시킨다. 

jsonObject는 데이터 포맷 중에 하나다. (예를 들어 html포맷, json포맷처럼)
childSelectBox가 void타입인 이유는 리턴타입이 필요없기 때문이다. 

AJAX는 호출한 곳에서 호출한 곳으로 데이터를 전달하기 때문에 특정 주소가 있는 리턴을 보낼 필요가 없다.

 

1번.  hashMap인스턴스를 생성해서 원하는 값을 뺄 수 있게 했다.    

 

2번.  submit( )방식이 get방식이면 한글처리가 안되서 server.xml에서 한글처리를 해줬다. 
       json은 톰켓 쪽이 아니여서 한글처리를 따로 해주어야 한다. utf-8세팅은 항상 위쪽에 있어야 한다. 

 

3번.  resquest는 화면에서 보내는 것이고 response는 화면에 파라미터를 내린다(받는다).

       submit통신은 뷰가 모델과 논리적 주소를 받아서 처리하지만 ajax는 모델이 아닌 response가 내려준다.
       예를들어, 모델로 받을때 model.addAttribute를 사용한 것처럼 response 메서드를 사용한 것이다.

       PrintWriter out = response.getWriter( );  PrintWriter는 리턴타입이다.

       콘솔에 resultMap에서 put( )로 뽑은 값은 AJAX전처리때문에 쿼리스트링 형식으로 나온다.

 

      *response로 내려주면 View가 아니라 mappingJacksonHttpMessageConverter가 받는다.
       mappingJacksonHttpMessageConverter는 종류가 많다. 
       우리가 response를 이용해서 내리면 수많은 if문이 있다.   
       예를 들어, http만 받는 애도 있고

       if문에 모델이면 뷰가 받고 
       또 if else해서 response는 mappingJacksonHttpMessageConverter이 받는다. 

       이런식으로 내부적으로 if문이 들어있다.
       mappingJacksonHttpMessageConverter는 스프링 3.0,

       스프링 4.0에서는 gsonHttpMessageConverter가 받는다.

     

4번.  쿼리스트링은 String타입인 writer( )메서드를 사용할 수 없다. 

       화면에 내리기 위해서 write( )을 사용하는데 String만 내릴수 있기 때문에 jsonObjectString으로 타입을 바꾼다.

       {key=value}  jsonObject타입이고  {"key" : "value"}  jsonObjectString타입이다. 
       이때 gson을 사용하면 된다. gson은 pom.xml가서 gson관련 dependency를 주입한다.

 

5번.  이제 String타입인 write( )를 사용할 수 있다. 

       콘솔을 보면 jsonObjectString으로 잘 나오는 것을 볼 수 있다.

 

 

 

jsonObjectString은 String이라서 값을 뽑을 수 없기 때문에 쿼리스트링 형식인 jsonObject형태로 또 바꿔야 한다.

 JavaScript메서드인 parse( )를 이용해서  jsonObject형식으로 바꿔줘야한다.

개발자도구에 jsonObject형식으로 나온 것을 볼 수 있다.

 

 

 


 

 

jQuery의 each문은 반복문으로 반복할때마다 익명함수를 실행한다.

 

$.each(childList, function(i, item) {
})

i는 배열 수이고 item은 프로퍼티다. 첫 번째 줄의 중괄호, 두 번째 줄의 중괄호..다.

 

prdCd를 selectBox에 나오게 하는 로직이다.

<script>

	var select = {
			
		displayChildSelectBox	:	function(childList){
			
			if (childList.length > 0) {
				
				$.each(childList, function(i, item){
					var optionStr = "<option value=" + item.prdCd + ">" + 
										 item.prdNm + 
									"</option>";
					
					$("#childSelectBox").append(optionStr);
				})
			} else {
				$("#childSelectBox").append("<option value''>없음</option>");
			}
		}
	}

	$(function() {
		//change()는  클릭한 selectBox로 클릭할때마다 값이 바뀐다.
		$("#parentSelectBox").change(function(){
			var thisParam = $(this).val();
			
            $("#childSelectBox").children().remove();
            
			$.ajax({
				url		:	"childSelectBox.do",
				data    :	{ "param" : thisParam},
				success	:	function(data){
					var jObj = JSON.parse(data);
					
					if (jObj.result === "SUCCESS") {
						select.displayChildSelectBox(jObj.childList);
					}
				}
			})
		});
	})
</script>

이렇게 brandCd에 따라 prdCd가 잘 나온다.

 

 

 

 

참고  :  한큐에 자바 수강내용

' > Javascript' 카테고리의 다른 글

JqGrid 서버사이드 format  (0) 2019.08.29
비동기식 JavaScript라이브러리 AJAX 2  (0) 2019.07.16
리터럴 방식의 배열  (0) 2019.07.08
자바스크립트 구성요소  (0) 2019.07.05
도큐먼트 레디가 동작하는 방법  (0) 2019.07.02

Java에서 나머지를 구하는 연산자인 모드에 대해 알아보겠다.

 

welcome_Web DB데이터
welcomeWeb select문
welcomeWeb2.jsp
welcomeWeb Controller
결과값

welcomeWebList라는 빈공간을 만들어줬다. 

welcomeWeb의 조건문을 돌려서 나온 값을 welcomeWebList에 담아 출력하는 로직이다.

welcomeWeb의 size는 db를 확인했을 때 7줄이다.

짝수를 구하는 조건문으로 배열은 0부터 시작하기 때문에 i에 0부터 6까지 차례대로 들어가서 값을 출력한다. 

결과값에서 홀수로 글번호가 나오는데 배열이기 때문에 짝수가 맞다.

 

참고로, List를 얻어올 때는 get( )이고 List를 추가할 때는 add( )이다.

welcomeWeb의 값을 get으로 얻어와서 welcomeWebList에 add로 추가해

결과값을 model.addAttribute( )로 화면에 내린다.

 

 

 

 

 

 

 

 

 

참고  :  한큐에 자바 수강내용

<script>
	var arrayLiteral = ["a", "b", "c"];
	
	$("#arr").val(arrayLiteral);
				
	alert(typeof $("#arr").val());
				
	$("#frm").submit();
</script>

<form id="frm">
	<input type="hidden" id="arr" name="arr"/>
</form>

split( )메서드의 사용법에 대해 알아보겠다.

arr의 타입은 문자열(String)이다.

문자열을 배열로 만들 때 사용하는 메서드는 split( )이다. 

괄호에 콜론( , )을 넣어주면 ,를 기준으로 나눈다.

Java는 배열을 쓸때 [ ]대괄호를 사용한다. 
String[ ]  arr = srt.split(",");
Java처럼 변수 앞에 타입을 적어주는 것을 정적타입언어라고 한다.
JavaScript처럼 타입을 안 적고 var를 쓰는 것을 동적타입언어라고 한다.

 

 


 

 

전체 배열을 출력하는 방법 

for (String a : arr)  {
    System.out.println(a);

을 기준으로 왼쪽(a)은 변수, 오른쪽(arr)은 배열이다. 

for문 돌때마다 배열의 0번째부터 순서대로 변수에 값을 넘겨준다.
배열의 타입과 변수를 담을 타입은 같아야한다. 

그리고 내가 마음대로 for문을 중간에서 멈출 수 없다.

 

 


 

 

배열을 콘솔에 찍으면 주소값이 찍힌다.

int는 기본타입이라고 한다. 기본타입은 stack에 변수와 값이 쌓인다.
반면에, 배열이나 String타입을 참조타입이라고 하는데, 참조하는 것을 가리키는 역할을 한다 얘네는 heap에 쌓인다.
heap이라는 공간에 값이 있고 그 값을 stack이 가리킨다. 
즉, heap 안에 있는 참조타입은 콘솔에 주소값이 찍힌다.
주소값이 아닌 값을 나오게 하려면 Arrays클래스에 toString( )를 사용한다. 

 

 


 

 

주소창에 http://localhost:8080/arrayInit/main.do?arr=a%2Cb%2Cc&pageName=main 라고 되어있는데
?뒤에는 콤마(,)가 인코딩 되서 이상하게 보인다. 보안상 이상한 문자열로 출력한다.

저 부분을 지우면 에러가 뜬다. arr이란 키를 화면에서 보내지 않았기 때문이다.

 

Null Exception이 발생한다.

에러의 발성원인은 값이 null이 아니라 split를 썼기 때문이다. 

null을 split한다는 것은 split할 것이 없기때문에 에러가 난다.
 String[ ] arr = srt.split(",");   <- 이거때문!! 

그래서 split을 쓸때에는 null처리를 해야한다. 해당 결과를 null인지 아닌지 체크를 꼭 해야한다.

화면에 데이터를 내릴 때는 @ModelMap타입을 사용한다. (ModelMap을 파라미터로 적어준다.)
controller에 model.addattribute("A",  B);  라고 적어주는데 A는 키 B는 벨류다.  

A는 Model에 담을 때 키의 명칭으로 외운다.

 

http://localhost:8080/arrayInit/main.do?arr=a%2Cb%2Cc&pageName=main 

?뒤에 주소창을 지워도 에러가 나지 않는다.

 

 


 

 

열거형 인터페이스Enumeration을 이용해서 배열을 출력해본다.

request.getParameterNames( ); 은 열거형 인터페이스 타입이다. 

 

Enumeration은 객체들의 집합에서 각각의 객체들을 한순간에 하나씩 처리할 수 있는 메소드를 제공하는 켈렉션이다.

getParameterNames가 화면에서 올린 키를 여기에 다 넣어준다 (벨류X 키만!!)

열거형 인터페이스엔 커서가 하나씩 다 있다
열거형에서 화면에서 올린 키는 data이다. 자신의 데이터(벨류)인것이다. 
열거형 인터페이스는 암묵적으로 while문을 사용한다. 커서의 오른쪽에 있는 데이터를 준다(for문 돌고 주고 ...)
자기 데이터를 주면서 커서가 이동하는 형식이다.

화면에서 올린 키를 적어주면 값도 뽑아 낼 수도 있다.

 

 


 

 

checkbox는 name들이 같다. 같은 키(name)에 다른 값이 들어간다.

 

첫 번째, 체크박스를 클릭하고 submit하면 주소창에 내가 클릭한 체크박스의 값이 나온다.

이후에 여러 개의 체크박스를 클릭해도 콘솔창에 하나의 값만 출력된다.

request.getParameter( )때문이다. 얘는 하나의 키가 하나의 값을 가져온다.

 

reuqest.getParameterValues( )는 여러 개의 값을 가져올 수 있다. 

리턴타입은 string이다. 

한개든 여러개든 배열에 다 때려 박지 말고 하나일 때는 String으로 여러 개 일때는 배열로 담아 보낸다.

얘는 split 안 써도 되고 한 번에 배열로 받을 수 있다.

 

 

 

 

출처  :  한큐에 자바 수강내용

' > JAVA' 카테고리의 다른 글

Try Catch문으로 오류잡기  (0) 2019.07.18
나머지를 구하는 연산자 %(모드)  (0) 2019.07.12
화면에 데이터를 내리는 ModelMap  (0) 2019.07.04
HttpServletRequest 객체  (0) 2019.07.01
Controller(컨트롤러)의 역할  (0) 2019.07.01

배열은 하나의 변수에 여러 값을 가질 수 있다. 

체크박스나 라디오버튼에 많이 사용한다.
이거를 스프링이랑 연결하는 것이 중요하다.

 

배열은 두 가지로 선언할 수 있다. 바로 생성자 방식과 리터럴 방식이다.  
실무에서 생성자로 사용하지는 않는다. 왜냐하면 메모리를 차지하기 때문이다.  
생성자는 오브젝트를 가리키고 리터럴 방식은 원시를 가리킨다.

 

생성자 방식 선언

var array = new array("a", "b", "c");

리터럴 방식 선언

var array = ["a", "b", "c"];

 

배열은 인덱스가 0부터 시작한다.

<script>

	var arrayLiteral = ["a", "b", "c"];
	
	$(function() {
		alert("arrayLiteral :" + arrayLiteral[0]);
		alert("arrayLiteral :" + arrayLiteral[1]);
		alert("arrayLiteral :" + arrayLiteral[2]);
		
	})
		
</script>

이렇게 선언하면

012
배열이 0번째 값부터 출력된다.

 

메서드의 타입을 확인할 때 자주 쓰이는 JavaScript프로퍼티는 typeof다.

alert(typeof $("#arr").val());

배열의 타입이 String인 이유는 

input태그에 있는 hidden 속성에 값을 넣었기 때문이다. 값을 넣어주는 순간 다 string으로 변한다.

<script>

	var arrayLiteral = ["a", "b", "c"];
	
	$("#arr").val(arrayLiteral);
				
	alert(typeof $("#arr").val());
				
	$("#frm").submit();
</script>

<form id="frm">
	<input type="hidden" id="arr" name="arr"/>
</form>

어노테이션(@)의 선언목적은 무엇일까?

Spring에게 해당 파일의 역할을 알리고 그에 맞는 어노테이션을 지원하기 위해서다.

예를 들어,

@Controller을 쓰는 이유는 @Controller 하위에 있는 어노테이션(@)을 쓰기 위해서다.  
하위 어노테이션 중에 @RequestMapping이 있다.  
@RequestMapping은 @Controller이 적혀있지 않으면 사용할 수 없다. 

@Service과 @Mapper도 마찬가지다 .

 

 

mvc패턴은 

컨트롤러  -> 서비스  ->  서비스임플  ->  맵퍼  ->  DB  ->  서비스임플  ->  서비스  ->  컨트롤러

순으로 데이터가 이동한다.

controller  ->  service  ->  serviceImpl  ->  mapper  -> db(sql)로 갔다가 다시 와서 
논리적주소와 모델을 내려준다. 

 

이 MVC패턴에서의 데이터이동을 더 자세하게 보면

@Controller를 읽어들이는 애가 있는데  dispatcher-servlet이다. 
dispatcher-servlet은 화면(view)과 Controller사이에 있다.
(dispatcher-servlet가 데이터를 들고 컨트롤러로 이동하는데 컨트롤러가 받고 이동)

View에서 Controller로 바로 보내는 것이 아니라 dispatch-servlet에 있는 Adaptor가 보낸다. 
이 어댑터는 RequestMappingHandlerAdaptor다. 

이 Adaptor가 키와 벨류를 받는다.
참고로, Spring은 어댑터 방식이다. 어댑터가 다 이동시킨다.

 Adaptor가 @RequestMapping을 찾아가는데 다짜고짜 찾아가지 않는다.  

 




++참고  :  DI는 DI컨테이너(context.~.xml)에 등록되어있다. 여기에 등록되려면 자격이 있어야 한다.  
@Conponent이 적혀있는 DI만 등록할 수 있다. 
@Controller를 눌러보면 @Conponent이 적혀져 있는 것을 볼 수 있다. 

@Service, @Mapper에도 다 @Conponent가 적혀져 있다. 

이런 애들을 다 긁어서 bean으로 등록(DI)시켜주는 애가 dispatcher-servlet에 살고있는 ConponentScan이란 애다. 

 


 

mvc패턴은 Controller에서 DB까지 데이터가 이동했다가 논리적주소와 모델을 내려준다고 했다.
논리적주소와 모델을 내리는 애는 dispatcher-servlet에 살고있는 JstlView다. 얘는 화면을 그리는 애다.

이 JstlView는 화면(html)을 그리다가 동적으로 생성되는 부분(C태그)을 만나면

Controller에서 받은 모델을 바라보고 내린다. (JSTL을 말함)
모델을 참고해서 내리기 때문에 JstlView이다. 

JstlView가 dispatcher-servlet한테 주는데 사람의 눈으로 볼 수 있는 상태가 아니기 때문에

servletContainer 한테 주고 이 컨테이너는 브라우저 통신(HTTP통신)으로 파싱해서 브라우져에 뿌려준다. 
그냥 뿌리는 것이 아니라 논리적주소를 참고해서 브라우져에 뿌려준다.

http통신(화면요청)에서 톰캣서버가 일어나서 dispatcher-servlet로 가고 

dispatcher-servlet에서 RequestMappingHandlerAdaptor가 받는다. 

RequestMappingHandlerAdaptor가 컨트롤러에 @requestMapping을 찾아간다.
모델이랑 뷰를 생성해서 dispatcher-servlet한테 주고 

dispatcher-servlet에 있는 JstlView가 화면을 생성하는데 c를 만나면 모델을 참고하는데
dispatcher-servlet가 이것을 다시 받아 servletContainer가 http통신을 통해서 파싱해서 사람눈으로 보여준다.

정리  :  
dispatcher-servlet한테 http요청을 하면 dispatcher-servlet는 Controller한테 요청을 해서 모델을 생성한다.
Controller는 dispatcher-servlet한테 모델과 뷰를 반환한다.
dispatcher-servlet는 뷰한테 모델을 주고 뷰는 생성을해서 dispatcher-servlet한테 준다.
dispatcher-servlet는 http응답을 한다.

 

 

 

출처  :  한큐의 자바 수강내용 참고

+ Recent posts