2016 IGRUS Hack Festival
대회일자 : 5월 21일 ~ 5월 22일
공동제작자 : 임준수, 김정현, 연준모, 곽진우, 조은희, 최정무
템플릿 출처 : http://blog.naver.com/PostThumbnailView.nhn?blogId=metalpan13&logNo=40209691660&categoryNo=46&parentCategoryNo=&from=postList
탑크리에듀에서는 자바 기초부터 자바를 활용하여 실무에서 즉시 활용할 수 있도록 네트워크, 스프링프레임워크, MyBatis까지 자바개발자가 필요로 하는 모든 스킬을 한 교육과정에 담았습니다. 10일동안 학습하신다면 당신도 자바개발자로 거듭날 수 있습니다. 본 과정은 평일주간반, 평일야간반으로 개설되었습니다.
초보자, 비전공자라도 할 수 있습니다. 지금 도전하세요!
2016 IGRUS Hack Festival
대회일자 : 5월 21일 ~ 5월 22일
공동제작자 : 임준수, 김정현, 연준모, 곽진우, 조은희, 최정무
템플릿 출처 : http://blog.naver.com/PostThumbnailView.nhn?blogId=metalpan13&logNo=40209691660&categoryNo=46&parentCategoryNo=&from=postList
탑크리에듀에서는 자바 기초부터 자바를 활용하여 실무에서 즉시 활용할 수 있도록 네트워크, 스프링프레임워크, MyBatis까지 자바개발자가 필요로 하는 모든 스킬을 한 교육과정에 담았습니다. 10일동안 학습하신다면 당신도 자바개발자로 거듭날 수 있습니다. 본 과정은 평일주간반, 평일야간반으로 개설되었습니다.
초보자, 비전공자라도 할 수 있습니다. 지금 도전하세요!
2013년 8월 31일에 올렸던 speakerdeck에 올렸던 자료 백업
https://speakerdeck.com/perhapsspy/mweonji-moreujiman-balpyo-aspeseo-djangoro-olmgyeogan-sayeon
---
한 개발자의 성장기(아니 삽질기)입니다.
ASP 개발을 하다가 Django를 쓰게 된 이야기를 간략하게 재미위주로 적어보았습니다.
자바개발시 모델객체를 생성할 때 setter/getter/toString/hashCode/equals 메소드를 만드는데 이럴 경우 클래스 파일의 소스가 길어지고 복잡해지는데, 이를 해결하기 위해 롬복(Lombok)을 사용하죠, 자바개발 하시는 분이라면 알아두시면 유용하리라 생각 됩니다.
스프링 WEB MVC에서 컨트롤러에서 예외처리하는 방법에 관해 설명한 PPT 입니다.
@ExceptionHandler는 스프링 컨트롤러에서 정의한 메소드에서 기술한 예외가 발생되면 자동으로 받아낼 수 있는데 이를 이용하여 컨트롤러에서 발생하는 예외를 View단 JSP등으로 보내서 처리할 수 있으며@ControllerAdvice는 스프링3.2 이상에서 사용가능하며 @Controller 나 스프링 4.0이상에서 지원하는 @RestController 에서 발생하는 예외 등을 catch하는 기능을 가지고 있으며 클래스 위에 @ControllerAdvice를 붙이고 어떤 예외를 잡아낼 것인지 메소드 상단에 @ExceptionHandler(예외클래스명.class)를 기술합니다. 스프링4.0이상에서는 특정한 컨트롤러만 지정해서 캐치할 수 있죠
Scala, Spring-Boot, JPA를 활용한 웹 애플리케이션 개발 과정에 대해 다룬다. Spring-Boot와 JPA 조합만으로도 생산성 있는 웹 애플리케이션 개발이 가능하다. 이 조합만으로도 충분히 의미가 있지만 여기에 Scala라는 약간은 불편한 듯 보이는 언어를 도입함으로써 얻을 수 있는 즐거움을 공유한다. Spring-Boot + JPA 조합에 Scala를 적용하면서의 좌충우돌 경험담을 전한다.
3. 초기화 파라미터(1)
• 하나의 서블릿 내에서 계속해서 참조하고자 하는 정보가
있음 (책에서는 admin email을 예시로 제시함)
• DD(=배포서술자) web.xml에서
<servlet>
.... 코드 생략 ....
<init-param>
<param-name>adminEmail</param-name>
<param-value>admin@abc.com</param-value>
</init-param>
</servlet>
5. 초기화 파라미터(3)
• 아래 코드가 의미하는 바는
• 이미 servletConfig 객체가 가 있다는 뜻이겠죠?
• 이 일은 서블릿이 초기화 될때 -> init(servletConfig) 때 생
성됩니다
out.println(getServletConfig().getInitParameter("adminEmail"));
6. 이를 절차적으로 표현하면
• 1. 컨테이너가 배포서술자를 읽었는데 <init-param> 이 있으면 -> 2.
ServletConfig 인스턴스를 만들어 줍니다(서블릿당 한개씩)
서블릿당 한개씩 == <servlet></servlet> 개수 만큼 인스턴스 생성
• 3. 컨테이너는 <init-param> 내에 있는 이름과 값을 확인한 후
ServletConfig 객체에 저장해 주고
• 4. 이후 컨테이너가 서블릿 클래스 인스턴스를 생성하고
• 5. 생성한 후에 init의 인자로 ServletConfig(=> init(ServletConfig) )
를 진행함으로써 서블릿 초기화 파라미터를 공유할 수 있게 됨
7. 컨텍스트 초기화 파라미터(1)
• 이전 초기화 파라미터를 활용하면 이런것이 가능하겠죠?
<servlet> —- 위 생략 —-
// 메일 관련 servlet
<context-param>
<param-name>MailHelp</param-name>
<param-value>mail_help@naver.com</param-value>
</context-param>
</servlet>
<servlet>
// 카페 관련 servlet
<context-param>
<param-name>CafeHelp</param-name>
<param-value>Cafe_help@naver.com</param-value>
</context-param>
</servlet> —- 아래 생략 —-
8. 컨텍스트 초기화 파라미터(2)
• 근데 만약 한개의 통합된 help 이메일을 제공하고 싶다면?
<servlet> —- 위 생략 —-
// 메일 관련 servlet
<context-param>
<param-name>help_intergrated</param-name>
<param-value>customer_help@naver.com</param-value>
</context-param>
</servlet>
<servlet>
// 카페 관련 servlet
<context-param>
<param-name>help_intergrated</param-name>
<param-value>customer_help@naver.com</param-value>
</context-param>
</servlet> —- 아래 생략 —-
?????????
9. 컨텍스트 초기화 파라미터(3)
• 지금 우리가 생각한것?
어 코드중복이다
한번의 수고로 프로그램을 제어하고 싶다
해결책?? ->> 다음장
10. • 지금까지 4번 등장한
컨텍스트 초기화 파라미터(4)
컨텍스트 초기화 파라미터
가 답입니다
11. How To Use
컨텍스트 초기화 파라미터?(5)
• 왼쪽을 오른쪽과 같이 만들어 주면 됩니다
<servlet> —- 위 생략 —-
// 메일 관련 servlet
<context-param>
<param-name>help_intergrated</param-name>
<param-value>customer_help@naver.com</param-
value>
</context-param>
</servlet>
<servlet>
// 카페 관련 servlet
<context-param>
<param-name>help_intergrated</param-name>
<param-value>customer_help@naver.com</param-
value>
</context-param>
</servlet> —- 아래 생략 —-
<context-param> —- 위 생략 —-
<param-name>help_intergrated</param-name>
<param-value>customer_help@naver.com</
param-value>
</context-param>
<servlet>
// 메일 관련 servlet
</servlet>
<servlet>
// 카페 관련 servlet
</servlet> —- 아래 생략 —-
12. 그러면 서블릿에서
컨텍스트 초기화 파라미터에
어떻게 접근하나요? (6)
• 이렇게요
out.println(getServletContext().getInitParameter("adminEmail"));
읭? 뭐가 달라요?
out.println(getServletConfig().getInitParameter("adminEmail"));
out.println(getServletContext().getInitParameter("adminEmail"));
13. 좋은 방법은 아닌것 같지만
전역변수와 지역변수 개념을 활용해
이해해 보면 . . .
14. 어 근데..? 지난학기에
객체지향적으로 프로그래밍 작성하자고
교수님이 말씀하셨는데??
왜 지금까지 String 타입의 이메일 주소만 공유해?
나 객체 공유할래
15. 객체를 공유해 볼까?
• 음 우선 DD에는 문자열 밖에 못들어 간다고 하네?
• 그러면 문자열 받아와서 객체를 생성하게 해주는
어떤 친구를 만들면 되겠다
• 음 우리가 배운 MVC 패턴을 고려할 때 C가 이 역할을 담당
하면 좋을것 같네??
• 좋아 control 역할을 해주는 서블릿을 만들고 그 서블릿이
객체를 만든 후 객체가 공유될 수 있도록 속성에 묶어두게
하면 되겠네?
17. 뭔가 잘못된것 같은데
고쳐볼사람?
저요!
서블릿은 자신이 호출 되어야지만
동작할 수 있어요
control 역할을 해줄 서블릿
즉 객체를 만든 후 객체가 공유될 수
있도록 속성에 묶어줄 서블릿이
먼저 호출되지 않으면
문제가 생길것 같아요
18. 그래서 필요한 것이 리스너!
• JSP도 아니고 서블릿도 아닌 어떤 자바객체
• 초기화 목적으로 실행될 어떤 객체
•그것이 바로 리스너
19. ServletContextListener는
뭐해요?
• 컨텍스트가 초기화 되는 것을 알아 차립니다
(초기화 = 애플리케이션이 배포됨)
• Servlet Context로 부터 컨텍스트 초기화 파라미터를 읽음
• 데이터 베이스 연결을 위한 초기화 파라미터를 사용함
• 컨텍스트가 종료되는것을 알아요
20. 리스너는 어떻게 만들까요?
• 우선 Web.xml에 listener 항목을 추가해 줍니다
<listener>
<listener-class>
com.example.MyServletContextListener
</listener-class>
</listener>
앗! 단 해당 클래스는 반드시 ServletContextListener 인터페이스를
상속받고 있어야 해요
21. 이렇게 말이죠
public class MyServletContextListener implements
ServletContextListener {
public void contextInitialized(ServletContextEvent event){
servletContext sc = event.getServletContext();
String dogBreed = sc.getInitParameter("breed");
Dog d = new Dog(dogBreed);
sc.setAttribute("dog", d);
}
}
22. 이후 그냥 속성에 객체를
속성에 저장해 주면 되요
public class MyServletContextListener implements
ServletContextListener {
public void contextInitialized(ServletContextEvent event){
servletContext sc = event.getServletContext();
String dogBreed = sc.getInitParameter("breed");
Dog d = new Dog(dogBreed);
sc.setAttribute("dog", d);
}
}
23. 그러면 서블릿에서는
어떻게 가져오나요?
public class ListenerTester extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
servletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Dog dog = (Dog) getServletContext().getAttribute("dog");
out.println("Dog's breed is : "+ dog.getBreed());
}
}
getAttribute의 return값은 Object!!!
24. 리스너는 8개가 있다고 해요
• 216페이지를 참조하세요
• 우리는 다시 context 이야기로 돌아가도록 합시다
25. Context 생존범위는 스레드에
안전하지 못하다고 해요
• 그 이유는 서블릿이 멀티 스레드 기반으로 실행되는데
요청이 동일한 서블릿으로 부터 온 것인지 다른 서블릿으로
부터 온 것인지 알지 못하기 때문이라고 합니다
26. 책에서 보인 예시
• 서블릿1이 A를 10 B를 5로 설정하였다
• 그런데 서블릿2가 와서 A를 7로 바꾸어 놓았다
• 서블릿 1은 A를 불러오면 당연히 10이 return될 것이라 생각
했다
• 하지만 7이 왔다
34. 이 문제를 해결하기 위해
public void doGet(어쩌구 저쩌구) throws 어쩌구, 저쩌구 {
... 코드 ...
synchronized(session){
getServletContext().setAttribute("foo", "22");
getServletContext().setAttribute("bar", "42");
out.println(getServletContext().getAttribute("foo"));
out.println(getServletContext().getAttribute("bar"));
}
... 코드 ...
}
35. 아 도데체 어떤 것들이
스레드로 부터 안전한가요?
• Request 속성 및 지역변수
36. 3장 스터디에서 보았던 코드
public void doGet(어쩌구 저쩌구) throws 어쩌구, 저쩌구 {
JSP단으로 보내줄 데이터를 열심히 가공합니다
JSP단으로 보내줄 데이터를 정말 열심히 열심히 가공합니다
... 코드 ...
JSP단으로 보내줄 데이터를 열심히 가공했어요
RequestDispatcher view = request.getRequestDispatcher("result.jsp");
view.forward(request, response);
}
37. 여기에 flush가 들어가면?
public void doGet(어쩌구 저쩌구) throws 어쩌구, 저쩌구 {
JSP단으로 보내줄 데이터를 열심히 가공합니다
JSP단으로 보내줄 데이터를 정말 열심히 열심히 가공합니다
... 코드 ...
JSP단으로 보내줄 데이터를 열심히 가공했어요
os.flush();
RequestDispatcher view = request.getRequestDispatcher("result.jsp");
view.forward(request, response);
}
IllegalStateException
38. flush() 라는 것은
• 클라이언트에게 응답을 보냈다.
• response를 내려 보내라
• 끝났다 라는 뜻이므로
• 이미 request를 쓸 수 없는 상태가 되어 버렸다
IllegalStateException 발생 원인