package portal.control.web; //경로 중요
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import portal.commons.data.Box;
import portal.service.BoardService;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration //이거 중요
@EnableWebMvc
@ContextConfiguration(locations = "classpath:conf/context-*.xml")
public class AdminBoardTest {
@Autowired
private BoardService boardService;
// 잊지말자 접근제한자ㅜㅜ
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before // JUINT껄로 임포트
public void setup() {
// mockMvc 사용하기 위해 builder와 wac객체를 이용하여 setup!
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testGetBoardList() {
// fail("Not yet implemented"); 없다면 아무것도 검증하지 않으므로 성공임....
}
@Test
public void testGoBoardInfoPop() {
// fail("Not yet implemented");
try {
Box box = new Box();
box.put("s_board_code", "NOTICE");
box.put("program_code", "BOARD");
box.put("action_mode", "modify");
box.put("id", "64");
Map view = boardService.getBoardView(box);
assertNotNull(view);
} catch (Exception e) {
}
}
@Test
public void testGoBoardInfoPopMock() {
// MockMvc객체로 하는 테스트
try {
System.out.println(mockMvc);
MultiValueMap<String, String> info = new LinkedMultiValueMap<>();
info.add("s_board_code", "NOTICE");
info.add("program_code", "BOARD");
info.add("action_mode", "modify");
info.add("id", "64");
mockMvc.perform(get("mg/board/goBoardInfoPop.do") // 1, 2 perform 어떤 메소드,,, 어떤 url인가를 지정하는 것
.params(info)) // 3
.andDo(print()) //andDo 결과확인을 위해...print 콘솔에 출력
.andExpect(status().isOk()).andReturn(); // 4 성공 할꺼를 예상하고 결과값중에 출력란것..
assertTrue(true);
} catch (Exception e) {
}
}
@Test
public void testGoBoardAction() {
// fail("Not yet implemented");
}
}
1. 패키지 경로 중요합니다. 그냥 대충 상위폴더에 만들고 진행했더니 에러 발생했습니다. 감싼 패키지name을 맞추고 진행했더니 되었습니다.
2 Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext //이 익셉션은 JVM이 내부의 클래스 정의 데이터 구조(class definition data structure)에서 Class를 찾지 못했다는 것을 나타낸다
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext //이 익셉션은 Classpath에 로드하고자 하는 Class가 발견되지 않았을 때 발생한다. 보통은 빌드에 문제가 있는 경우로 clean이나 Class파일 삭제 후 재빌드를 수행하여 해결한다
이런에러가 발생했습니다....
servlet과 관련된 에러들이 계속 발생했다..... 프로젝트 업데이트를 해도 발생했는데 ....
어찌저지....Modulepath에 JRE만 남겨놓고 나머지는 Classpath쪽으로 이동시키니깐 저 에러는 해결되었음...
org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.test.context.web.WebDelegatingSmartContextLoader]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:146) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:176) at org.springframework.test.context.support.AbstractTestContextBootstrapper.resolveContextLoader(AbstractTestContextBootstrapper.java:455) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:346) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:291) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:107) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:137) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:122) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:151) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:142) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104) at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70) at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28) at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:513) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext //이 익셉션은 JVM이 내부의 클래스 정의 데이터 구조(class definition data structure)에서 Class를 찾지 못했다는 것을 나타낸다
at org.springframework.test.context.web.WebDelegatingSmartContextLoader.<init>(WebDelegatingSmartContextLoader.java:63) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) ... 29 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext //이 익셉션은 Classpath에 로드하고자 하는 Class가 발견되지 않았을 때 발생한다. 보통은 빌드에 문제가 있는 경우로 clean이나 Class파일 삭제 후 재빌드를 수행하여 해결한다
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ... 36 more
13:43:41.637 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - GET "/mg/board/goBoardInfoPop.do", parameters={masked} 13:43:41.638 [main] WARN org.springframework.web.servlet.PageNotFound - No mapping for GET /mg/board/goBoardInfoPop.do
java.lang.AssertionError: Status expected:<200> but was:<404>
1. DI설정...이건 pom이 없어서 잘모르겠으나 여러 xml파일통해서 문제가 없어보이고 앞선 test가 문제없어 패스
문제는 어쩌다 본문한개를 콜백으로 화면 변경하여 데이터를 불러 왔더니 js가 안먹히는 겁니다.
아무것도.....그 어떤것도.......왜그런줄 몰랐는데 초고수님 말씀!!!
자바스크립트는 순차적으로 로딩~~~메인의 자바스크립트는 이미 불러왔는데 이후 불러온 본문jsp파일을 읽고 처리할 스크립트 적용 처리 없이 그냥 불러오니 이미 적용된 메인의 js가 안먹힌다......였어요..
그래서 메인의 js파일에서 본문의 b.jsp파일을 함수로 불러오면 먹히겠금 구성하였는데
그럼 파일을 다시 불러올때 불필요한 가비지 데이터가 생긴다.......... 사실 이부분도 어렵습니다...일단 기록!
이걸 해결하는 것이 클로저!
클로저란 ? 내부 함수가 정의 될 때 외부 함수의 환경을 기억하고 있는 내부함수를 말함/ 외부 함숴 안에서 선언된 내부 함수는 그 외부 함수의 지역 변수나 함수에 접근하여 사용할 수 있음.
클로저 함수의 기본 형태.
//외부 함수
function closuer(){
var count = 0; //변수 정의
function inner(){ // 내부 함수(클로저)선언
return count++;
}
return inner(); // 내부 함수 반환
}
//익명 함수를 이용하는 방법
function closure(){
var count = 0;
return function(){ //익명 함수(클로저) 반환
return count++;
}
}
클로저 함수 호출 예시
function outter(){ //외부 함수
var data = 1;
function inner(){ //내부 함수
return data;
}
return inner();
}
var fucnt = outter();
console.log(func)
값은 1이다.
원래는 outter 함수를 호출하지 않았기 때문에 지역변수 data는 사용하지 못하는 것이 일반적이지만 자바스크립트에서는 사용할수 있다는 것이 특이한 점이다.
또한 전역 변수를 대체하여 클로저를 사용할 수 있어서 전역 변수의 남용을 막을 수 있고 변수 값을 은닉하는 용도로도 사용 할 수 있다.
어휘적 환경(Lexical Environment)
function makeAddr(x){
return function(y){
retrun x+Y;
}
}
const add3 = makeAdder(3); //x = 3
console.log(add3(2)); //5 ;; y = 2 add함수가 생성된 이후에도
상위함수인 makeAdder의 x에 접근(기억)
const add10 = makeAdderA(10); //x = 10
console.log(add10(5)); //15
console.log(add3(1)); //4
add10과 add3은 다른 환경의 함수임으로 결국 결국 두 함수의 x 의 값은 다르다.
하지만 x의 값을 값자기 100이나 99 변경할수는 없다....add함수의 증감만 있을 뿐....이것을 은닉화!... 인것 같다^^
일부만 발최함........ 첨부파일을 저장시 먼저 임시 id를 얻어야 해서 ajax로 진행
var formData = new FormData($('form[name=noticeForm]')[0]);
formData += $("form[name=noticeForm]").serialize();
$.ajax({
type : 'post',
url : 'mg/board/goBoardInfoPop.do',
enctype : 'multipart/form-data',
data : formData,
processData: false,
contentType:false,
cache: false,
timeout: 600000,
success : function(data){
alert('공지사항을 등록하였습니다!');
Notice_write(data);
},
error : function(e){
alert('파일 등록 실패하였습니다.');
}
});
}
html form을 대체하는 FormData객체///// jsp본문의 form과는 별개이다.
이걸하면서 몇가지 필요한 함수 더 확인해 본다.
let formData = new FormData(); // 새로운 폼 객체 생성
formData.append('name','hyemin'); // 폼 데이터를 스크립트로 추가
formData.append('item','hi'); // <input name="item" value="hi"> 와 같다.
formData.append('item','hello'); // <input name="item" value="hello">
// 만일 HTML에 미리 form 태그가 있으면 제이쿼리나 자바스크립트로 가져올 수도 있다.
let formData1 = new FormData($("#form Id")); // 제이쿼리인 경우
let formData2 = new FormData(document.getElementById("form Id")); // 자바스크립트로 가져 올 경
formData.append(name, value)
// - form의 name 과 value 를 필드의 추가
// - input의 name 속성과 value 입력값 역할을 한다고 생각 하면 된다.
// 자바스크립트로 직접 form 태그를 생성
formData.append(name, blob, fileName)
// - input 의 type 이 'file' 인 경우에 사용
// - fileName은 file의 이름의 해당
formData.delete(name)
// - 주어진 name 으로 필드를 제거
formData.get(name)
// - 주어진 name 의 해당 하는 필드 value를 반환
formData.getAll(name)
// - append 함수로 추가시 name이 중복 가능
// - 따라서 주어진 name 의 해당 하는 필드의 모든 value를 반환
formData.has(name)
// - 주어진 name 의 해당하는 필드가 있을 경우 true, 없으면 false를 반환
formData.set(name, value)
formData.set(name, blob, fileName)
// - set 함수는 append 함수 처럼 필드를 추가
// - append와 비슷한 set 메소드는 set도 추가를 해주기는 하지만, 기존 key가 있으면 그 key값을 모두 덮어씌워버린다
깃허브 도메인......ip타입 공유기로 도메일 살수 있다. sonof.iptime.org:8613 도메인은 ip와 매핑되어 있다. 한개의 IP에 여러 프로그램이 연결되어 있어 구분할 수 있는 port번호를 부여
배포 하는 방법/// 1. 컴퓨터 필요. (2명 결원으로 한대는 DB server로 쓰고 있다. ) 2. 도메인. 공유기로 대체 가능 //1,2번을 aws로 대체 가능하나 1년후 비용이 어마함. 3. was (apache tomcat)
1. 이클립스 = 에서 war파일을 만들어서 프로젝트 배포 준비 export-> War file(압축파일.모든 정보가 있다). -> (webporjet : 프로젝트 이름을 넣으면 그것이 파일명이 된다 ) (destinetion: 저장시킬 폴더 선택) EXport sourece Files 체크하여 저장시킨다......strap(프로젝트명).war 파일이 생긴다.
2. 해당 컴퓨터에 tomcat.apache(8.5버전)의 해당 버전을 다운로드 한다.......이건 새컴이라는 가정. 있으면 패스 윈도우에서 그냥 톰캣을 실행을 시킬려면 다운받은 톰캣폴더/ conf 폴더/ server.xml/안의 <Connetctor port ="9898" protocol="http/1.1"> 부분을 원하는 포트번호로 변경 톰캣 폴더에서 cmd.exe실행 dir목록 확인 .bat 배치파일을 이용해서 ....startup.bat파일을 입력 엔터하면 서버실행된다. 한글은 깨질수 있음. 그러면 localhost:9898 실행하면 된다. shutdown.bat은 서버를 닫는것이다.
톰캣의 webapps폴더로 가서 이클립스에서 받은 strap.war파일을 떨거주면된다. (이파일은 학원 유틸배포에 있다)
192.168.60.8:9898/strap/ db 서버 ip주소에 (ipconfig)직접 입력--이건 사설 대여기라서 밖에서는 연결안됨///밖에서는 공인된 ip인 도메인이 필요하다.
"/"으로 인터넷 확인하는 방법 톰캣의 1. server.xml로 간다. 1. 한줄 추가 위치는 <Host></Host>안에 넣어야 한다. <Context path="" docBase="strap" reloadable="false"/> 추가하면된다. 서버를 실행시키면 톰캣 webapps에 자동으로 프로젝트 폴더가 생긴다.
공인된 IP 도메인과 연결시키는 방법
공유기 특수 기능 ..ddns 설정 //호스트 이름(sonof.iptiom.org) 을 넣으면 ip주소와 연결된다.란 것이다. 포트번호는 고급설정의 nat / 라우터 관리 의 포트로워드 설정을 가면 설정할수 있고.외부포트(9999) 내부포트(9898)로 설정 호스트이름 : 외부포트 설정한다는 것은 외부에서 sonof.iptime.org:9999 로 연결하면 결국 192.168.60.8:9898 로 연결해준다는 것을 설정하는 것이다. 포트번호를 별도 승인해줘야 하는데 방화벽에서 프로토콜 포트번호/ 특정로컬포트 9898을 넣어줘야 한다. 핸드폰에서 똑같이 저장하면 된다.