하나의 was에 여러개의 프로젝트(컨텍스트)가 존재할 경우 일반적으론


서로간 세션의 공유가 되지 않는다. 


이때 각 컨텍스트간의 세션이 공유될 수 있는 방법을 알아보자.



1. 서버의 context.xml의 변경


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context>
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs


저 위의 컨텍스트를 아래와 같이 바꿔준다.


1
2
3
4
5
6
7
8
9
10
<!-- The contents of this file will be loaded for each web application -->
<Context crossContext="true">
 
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
 
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
cs



2. server.xml 변경


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

cs


1
 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" emptySessionPath="true"/>
cs


emptySessionPath="true" 를 추가 한다.



3. 세션 세팅


1
request.getSession().getServletContext().setAttribute("ssUserId", userId);

cs


기존의 방법에서 가운데 getServletContext()를 추가 하여 준다.


root로 지정되어 있지 않는 컨텍스트에선 

getServletContext("/sample") 와 같이 컨텍스트명을 지정하여 준다.



4. 세션 겟


1
String ssUserId =  (String) request.getSession().getServletContext().getContext("/").getAttribute("ssUserId");
cs


가지고 올땐 위와 같이 가져오며 루트가 아닌 컨텍스트에서 set 한 경우엔 getContext("/sample") 와 같이 컨텍스트 명을 넣어 사용 하면 된다.




DWGViewX 를 사용해 웹에서 cad 파일을 볼 수 있도록 해주는 도중 파일을 불러오지 못하는 오류가 발생 하였다.


일단 


<object id="DWGViewX" codebase="http://www.autodwg.com/dwgviewx/dwgviewx.cab" height="520" width="700" classid="clsid:AC53EFE4-94A7-47E6-BBFC-E9B9CF322299">

                        <param name="_Version" value="65536">

                        <param name="_ExtentX" value="18521">

                        <param name="_ExtentY" value="13758">

                        <param name="_StockProps" value="0">

                       <param name="DrawingFile" value="불러올 파일이 있는 경로">

                        <param name="ShowToobar" value="-1">

                        <param name="ShowLayoutBar" value="1">

                        <embed name="DWGViewX" width="700" height="520" type="DWGVIEWXLib.DwgViewX" showtoolbar="-1" showlayoutbar="1" pluginspage="http://www.autodwg.com/dwgviewx/dwgviewx.cab" title="undefined">

                    </object>



사용방법은 html안에 이렇게 사용해 넣으면 된다.


DrawingFile 파라메터의 밸류값에 불러올 파일이 있는 경로를 지정해 주면 된다.


절대경로를 사용한다면 클라이언 PC의 경로를 뒤진다 (ex) C/programs/..........기타등등)


서버에 있는 파일을 보여주고 싶다면


경로값이 해당 dwg파일을 다운로드 받는 url을 넣으면 해당 파일을 보여준다.



문제는 자꾸 no mapping uri가 나타나면서 에러가 나고 하얀색 화면만 나타난다는 점이다.


해당 경로를 브라우저의 URL창에 넣으면 파일은 정상적으로 다운로드가 되지만 dwg뷰어에서는 해당 url를 찾지 못한다고 나올 뿐이다.


어노테이션 설정에 문제가 있는 건지 한참을 뒤져보다가 원인을 찾게 되었다.


원인은 DrawingFile의 value값이 중간에 인코딩이 되어 요청된다는 것이다.


한글은 깨지고 영문은 전부 소문자로 변환된 후 요청을 한다.


해결방법은 그냥 호출받는 주소를 전부 소문자로 바꿔줘 버렸다...

파일이름은 파일이 업로드 될때 실제 저장된 파일이름은 UUID로 바꾼후에 영문소문자로 바꿔서 저장을 하도록 했다.


이제 도면파일 잘나온다.


액티브X 사라져버렸으면 좋겠다.

파일을 업로드 하고 다운로드 받는 과정에서 저장소에 동일한 파일이름을 가진 파일을 업데이트 하게 되면 저장되는 파일의

이름을 바꾸어 주어야 한다.


동일한 이름이 있을때마다 파일명 뒤에 카운트숫자를 달아 주는 방법을 사용한다거나 

UUID 같은 것을 파일명으로 바꾸고 저장한다거나 날짜순으로 저장하는등의 여러가지 방법들이 있다.


그렇다면 다운 받을때는 파일명이 uuid나 일반 사용자가 알아보기 힘든 파일명을 사용하면 안되기 때문에


다운로드 받을때는 다시 원래 파일명으로 다운 받도록 해주어야 한다.


그렇기 위해서는 파일업로드와 함께 DB에 해당 파일의 이름이나 이름이 포함된 경로를 넣으며 실제저장되는 변경된 파일이름과 원본파일의 이름 두가지를 넣어 주어야 한다.


문제는 여기서 발생한다. 흔히 나와있는 파일 업/다운로드 로직이나 전자정부 프레임워크를 사용하다보면 파일을 다운받을때 실제 저장된 파일이름만 가져와서 다운로드 받는 로직으로 짜여져 있고 단순히 복사해서 붙여넣기를 하는 방법으로 사용하니 다운받을때 디비에서 이름두가지를 가지고 오고 나서 이후에 어떻게 해야 할지 모르는 경우가 생긴다.


대표적으로 컨트롤러에서 


 return new ModelAndView("download", "downloadFile", file); 


이렇게 리턴값을 modelAndView로 사용하는 방법에서 실제저장된 파일명을 바꿔서 사용하는 방법을 알아보자.




일단 리턴되는  ModelAndView("download", "downloadFile", file) 여기서 


'download'는 dispatcher-servlet.xml 에서 지정되는 값으로. 디스패쳐 파일을 열고나서 download을 검색해 보면



<bean id="download" class="egovframework.XXXXXXXX.XXXXXXX.XXXXXXXX.DownloadView" />


와 같은 형식으로 쓰여 있을 것이다. 'download'라는 요청을 받으면 해당 클래스를 실행하겠다는 중간의 XXX표는 패키지 경로이다.


DownloadView 클래스를 열어 보면 



File file = (File) model.get("downloadFile"); <- 이런식으로 modelAndView의 두번째 인자를 불러오며 결과는 downloadFile뒤에 쓰여진 file이 된다.



아래로 좀 내려보면 


fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");


이런식으로 해당 파일의 이름을 꺼내서 


 response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");


이렇게 파일이름을 셋팅을 하는데


여기서 셋팅되는 fileName만 원래 파일이름으로 바꿔주면 되는 것이다.




이제부터 어떻게 해야 하는지 방법을 알아보자



우선 다운로드 URL이 어노테이션 되어 있는 컨트롤러에서 


리턴되는 값을 return new ModelAndView("download", "downloadFile", file); 가 있는 컨트롤러를




fileName = new String(fileName.getBytes("iso-8859-1"), "UTF-8"); // 파일이름 깨지니까 인코딩

    realName = new String(realName.getBytes("iso-8859-1"), "UTF-8");

//propertiesService.getString("Globals.FmsFilePath")는 미리 지정해놓은 경로니까 그냥 파일경로라고 생각하면 됨

    String fullPath = propertiesService.getString("Globals.FmsFilePath") + "\\경로\\" + fileName;

    

   File file = new File(fullPath); // 실제 파일 경로를 지정해 생성한 파일

   File file2 = new File(realName); // 바꿀 파일이름만 넣어놓은 파일  realName은 String값이다.


   ModelAndView mav = new ModelAndView();

   mav.setViewName("download");

   mav.addObject("downloadFile", file); // 실제 저장된 파일

   mav.addObject("realFileName", file2); //db에 저장해 놓은 원래 파일이름

   

   if(!file.exists()){

    return null;

   }

    //    return new ModelAndView("download", "downloadFile", file);

   return mav;



이렇게 바꾸어 주도록 하자.


즉 ModelAndView에 두개의 오브젝트를 넣어서 넘기는 것이다.



그리고 다시 DownloadView 로 가서 


 fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");

  response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");


위의 코드를 아래와 같이 바꿔주도록 하자.


   File file2 = (File) model.get("realFileName");

String fileName="test";

try{

fileName = URLEncoder.encode(file2.getName(),"UTF-8").replaceAll("\\+", "%20");

}

catch(Exception e){

 fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");

}

 response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");




이렇게 하면 끝! 완성! 해결!





버그 예.


1. 클라이언트(브라우저)에서 jquery ajax 를 수행하여 GET request를 한다.

2. 서버가 GET request를 받고 routing을 수행하여 해당하는 데이터를 response한다.


Chrome, FF, Safari 의 경우 - 서버가 보낸 response를 받고 데이터를 확인한다.

IE 의 경우 - 서버가 보낸 response는 받으나 데이터가 없다.




서버쪽 로그를 확인해보니 특정한 GET 요청을 서버가 받지 못하고 있었다.


헌데 alert(‍), console.log() 등을 이용해서 확인해본 결과


ajax 수행은 error가 나지 않고 제대로 success 를 띄움



재밌는건 익스플로러의 개발자도구를 띄워놓은 상태에선 값을 잘 받아 온다는 점이다.




원인 및 해결 방법



URL이 같으면 IE의 ajax 연결은 cache를 사용하고 갱신하지 않는다는 것이다.


그래서 ajax 연결 시 URL을 매번 바꾸어주어야 한다는 것


간단한 해결 방법은 시간과 같이 매번 변하는 파라메터를 같이 날려 주는 것


http://localhost:8080/session

=> http://localhost:8080/session?1260790889296



제이쿼리에서는 

jQuery.ajaxSetup({cache:false});

와 같이 캐쉬사용을 끄는 옵션도 있지만 간혹 적용이 안되는 경우도 있는 것 같다.


전자정부 프레임워크를 사용하다 보면 미친듯한 메모리 점유율에 이클립스가 뻗어버릴때가 종종 있다.


이경우 이클립스에 힙메모리 할당만 어느정도 조절해 준다면 보다 원활한 작업을 진행 할 수가 있다.


먼저 eclipse.ini 파일을 열어 본다



-vmargs << 요 아랫부분을 수정해 준다.



---- 이 아래 부분을 복사해 넣는다 --------

-Dfile.encoding=UTF-8

-Dosgi.requiredJavaVersion=1.7

-Xverify:none

-XX:+UseParallelGC

-XX:-UseConcMarkSweepGC

-XX:PermSize=128M

-XX:MaxPermSize=128M

-XX:MaxNewSize=128M

-XX:NewSize=128M

-Xms512m

-Xmx512m

-----------요기까지--------------


-Xverify:none => 클래스의 유효성을 검사 생략. (시작 시간이 줄어 빨라진다.)
-XX:+UseParallelGC => 병렬 가비지 컬렉션 사용. (병렬 처리로 속도 향상)
-XX:+AggressiveOpts => 컴파일러의 소수점 최적화 기능을 작동시켜 빨라진다.
-XX:-UseConcMarkSweepGC => 병행 mark-sweep GC 수행하여 이클립스 GUI의 응답을 빠르게한다.
-XX:+CMSIncrementalMode=true => 점진적인 GC

-XX:PermSize=128M        => Permanent Generation(영구 영역) 크기(Out Of Memory 에러시 크기 조절)

-XX:MaxPermSize=128M  => 최대 Permanent Generation 크기

-XX:NewSize=128M         => New Generation(새 영역) 크기

-XX:MaxNewSize=128M   => New Generation(새 영역) 의 최대 크기


-Xms512m : 이클립스가 사용하는 최소 Heap 메모리
-Xmx512m : 이클립스가 사용하는 최대 Heap 메모리
                     최소와 최대를 같은 값으로 설정하면 오르락 내리락 하지않아 빨라진다.
[메모리 정의 예]
1 기가 이하 메모리인 컴퓨터인 경우 => -Xms256m -Xmx256m
2 기가 ~ 3 기가 메모리인 컴퓨터    => -Xms512m -Xmx512m
4기가 이상 메모리인 컴퓨터            => -Xms1024m -Xmx1024m




동적쿼리를 생성해야 하는 경우는 상당히 많다.


이번에 ibatis를 처음 사용하면서 편하긴 하지만 알아야 할것도 참 많다고 생각이 드는데


아무튼 ibatis에서 리스트를 받아와 쿼리문에 foreach문 같은 반복문을 생성하도록 하려면


iterate를 사용해야 한다.


사용법은


<iterate property="measureTypeList" open="(" close=")" conjunction="or">

<![CDATA[ TYPE_ID =#measureTypeList[]#]]>

</iterate>


이런식으로 사용이 가능 하다.


property는 받아오는 리스트의 이름


open는 반복문이 시작할때 들어가는 텍스트


close는 그 반대


즉 저렇게 돌리면


(TYPE_ID  =#measureTypeList[]# or TYPE_ID  =#measureTypeList[]# or TYPE_ID  =#measureTypeList[]#)



이런식으로 돌아간다 conjunction은 반복할때마다 들어갈 텍스트이다



그런데 저렇게 사용을 할때 


outOfBoundsException 에러가 나는 경우가 있다!!!


컨트롤러에서 보내는 parameterClass를 리스트로 만들어서 보냈는데! 왜!!! 왜 안돼는걸까!



ArrayList<String> measureTypeList = new ArrayList<String>();

measureTypeList.add("MEASURE_TYP_117");

measureTypeList.add("MEASURE_TYP_118");


컨트롤러에서 저런식으로 만들어서 바로 파라메터로 보내버렸을때 발생하는 에러 이다



위의 에러를 해결하기 위해서는


만들어 놓은 리스트를 hash맵에 담아서 보내야 한다


HashMap measureTypeListMap = new HashMap();

measureTypeListMap.put("measureTypeList", measureTypeList);



이런식으로 해쉬맵에 담아서 보내면 에러가 해결이 된다.



<select id="WidgetTagDAO.measureTypeList" parameterClass="HashMap" resultMap="widgetTag">

<![CDATA[

SELECT*

   

 FROM

 where

]]>

<iterate property="measureTypeList" open="(" close=")" conjunction="or">

<![CDATA[ TYPE_ID   =#measureTypeList[]#]]>

</iterate>

</select>

XML에서 작성하면 위와 같이 작성을 하면 된다.




이클립스를 켜면 


An error has occurred. See error log for more details. java.lang.AbstractMethodError 


라는 에러 메세지가 계속해서 나오는 경우가 있다


확인해보니 자바버전의 문제 였다


전자정부 프레임워크의 버전이 2.7 버전일 경우 jdk 1.7 이하의 버전을 써야 한다고 한다.


이클립스의 windows - preferences - Java - Copiler 에 가면 컴파일러 레벨 이라고 되어 있는 콤보박스에서


현재 설치되어 있는 jdk의 버전을 설정 할 수가 있다.


여러 프로젝트를 하면서 jdk의 버전을 각각 변경해야 하는 경우가 있는데 컴파일러 버전을 바꾸어 주는 것이


빠르고 편리한 것 같다.


회사에서 처음 노트북을 지급받고 이클립스 자바 등등등을 설치 한 후 실행을 해보면

404에러가 뜨는 경우가 많다. 경로를 찾지 못해서 나타나는 에러인데 

에러가 나는 부분도 없는데 에러가 나는 경우가 있다. 이런 경우 서버를 체크해보자!


보통 이런 경우는

서버에 루트 지정이 잘못된 경우이다.


해당서버 컨피그 폴더안에 있는


server.xml 파일 Context 태그 안에 path설정을 해주어야 한다. 


아마 path에 /프로젝트이름 

으로 되어 있거나 다른 이름들이 들어가 있는 경우일텐데

보통 그냥 "/" 이걸로 바꿔주면 실행이 될 것이다. 도메인 뒤에 다시 프로젝트이름이 나타나는건 보기 안좋기 때문에

그냥 저렇게 하는 듯 하다.



포스팅이 도움이 되셨다면 마우스를 조금만 움직여서 

공감하기를 눌러주세요 블로거에게 큰 힘이 됩니다~! 


spring tooling update 혹은

레퍼런스 에러가 나는 경우 

1.
help - check for update 를 통해 업데이트를 한후 재시작

2.
이클립스.ini 파일에 -clean 추가


포스팅이 도움이 되셨다면 마우스를 조금만 움직여서 

공감하기를 눌러주세요 블로거에게 큰 힘이 됩니다~! 

가끔 이클립스를 띄우면 나타나는 에러창이다.


뭐 업데이트 하려는데 삔또가 나갔다 이런말 같은데


Window -> Preferences -> Maven -> Download repository updates index on startup


로 해결하자.


포스팅이 도움이 되셨다면 마우스를 조금만 움직여서 

공감하기를 눌러주세요 블로거에게 큰 힘이 됩니다~! 

+ Recent posts