자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)

3,208 views

Published on

Java web development 01

자바 웹 개발 시작하기
(1주차 : 웹 어플리케이션 체험 실습)
2011. 10. 26

벌써 2년도 넘은 자료지만
그래도 필요하신분이 있을지 몰라서...
(지금보니 2년사이 많은것을 배운것 같네요 ㅎㅎ)

Published in: Technology, Education

자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)

  1. 1. 자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습) 2011. 10. 26 DEVELOPMENT #2 이덕곤
  2. 2. §  환경구축 Hello, world 데모 순서 (약 30분) §  VirtualBox 다운로드 및 설치 §  WindowsXP 설치 (빵집 다운로드 및 설치) §  JDK 다운로드 및 설치 §  Tomcat 다운로드 및 설치 §  Eclipse 다운로드 및 설치 (Java폴더 만들어서) §  UTF-8 설정 §  서버 만들기 §  JSP파일 만들어서 Hello, world! 출력하기
  3. 3. §  환경구축 어렵다는 말은 옛말(물론 서비스용은..) §  윈도설치시간 다운로드시간 제외하면 10분이면 OK §  다운로드 URL §  VirtualBox : https://www.virtualbox.org/ §  JDK : http://java.sun.com/ §  Tomcat : http://tomcat.apache.org/ §  Eclipse : http://eclipse.org/ §  빵집 : http://www.bkyang.com/
  4. 4. §  사실 거의 모든 웹 개발은 게시판 개발 (DB필요) §  다운로드 URL §  MySQL 설치 §  http://mysql.org/ §  SQLyog §  http://sqlyog.org/ §  http://code.google.com/p/sqlyog/downloads/list §  JDBC driver for MySQL §  http://www.mysql.com/downloads/connector/j/5.1.html
  5. 5. §  DB생성 CREATE DATABASE `study` CHARACTER SET utf8 COLLATE utf8_unicode_ci; §  테이블 생성 CREATE TABLE `test` ( `idx` int(11) NOT NULL AUTO_INCREMENT, `subject` varchar(500) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`idx`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  6. 6. §  JSP가 모든 것을 처리 웹 서버 ①요청 Web Browser ②HTML인 경우 HTML httpd ③JSP인경우 웹 컨테이너 웹컨테이너 JSP (빈즈호출) JSP ④<JSP:useBean../> ⑥다음 JSP호출 DB ⑤DB처리 모든 것을 처리하는 슈퍼 울트라 캡송 JSP JSP (결과뷰어) <% … %> ⑦<JSP:useBean../> BANS
  7. 7. §  JDBC 드라이버 로딩 Class.forName("com.mysql.jdbc.Driver"); Connection conn = null; Statement stmt = null; ResultSet rs = null; §  MySQL에 연결 String jdbcd = "jdbc:mysql://localhost:3306/study?” + "useUnicode=true&characterEncoding=utf-8"; conn = DriverManager.getConnection(jdbcd, “id”, “pw”); stmt = conn.createStatement();
  8. 8. try { // 여기에 DB 코드가 들어간다 } catch(SQLException ex){ out.println(ex.getMessage()); ex.printStackTrace(); } finally { // 사용한 Statement 종료 if(rs != null) try{ rs.close(); } catch(SQLException ex){} if(stmt != null) try{ stmt.close(); } catch(SQLException ex){} if(conn != null) try{ conn.close(); } catch(SQLException ex){} }
  9. 9. §  목록보기 쿼리 String query = "select * from test order by idx desc"; §  쿼리 실행 rs = stmt.executeQuery(query); while(rs.next()) { <%= rs.getString("idx") %> <%= rs.getString("subject") %> }
  10. 10. §  글 쓰기 쿼리 String query = "insert into test (subject) value ('"+ subject +"')"; §  글 수정 쿼리 String query = "update test set subject = '"+ subject +"' " + ”where idx = '"+idx+"'"; §  쿼리 실행 int count = stmt.executeUpdate(query); // 리턴값은 실행 수
  11. 11. §  페이지에 대한 클래스 정보 <%@ page contentType = "text/html; charset=UTF-8" %> <%@ page pageEncoding = "UTF-8" %> <%@ page import = "java.sql.*" %> §  완료 후 처리 <% if(count > 0) { %> <% response.sendRedirect("/"); %> <% } else { %>에러<% } %>
  12. 12. §  MVC모델로 나누어 처리 웹 서버 Web Browser ①요청 ②HTML인 경우 httpd HTML ③JSP인경우 웹 컨테이너 <<Controller>> Servlet or JSP ④<JSP:useBean../> <<Model>> 웹컨테이너 DB 빈즈 ⑦적절한 View로 포워딩 <<View>> <<View>> JSP JSP ⑤DAO 클래스 사용 <<DAO>> 클래스 ⑥ DB 접속 및 처리
  13. 13. §  핵심은 DispatcherServlet
  14. 14. §  스프링 및 기타 프레임워크로 구성 5.1.XX 개발 : Eclipse 3.7.1 (SVN : 버전관리, Log4j : 로그) Java SE 6 update X Java EE 5 Spring MVC : WEB (컨트롤 부분) JSP 2.0(JSTL 1.1, EL) (뷰 부분) MySQL Connector For Java 5.1.XX 2.3 DAO (모델 부분) POJO Bean : Domain, Service (비즈니스 부분) Tomcat 6.0.XX (Servlet 2.5, JSP 2.1)
  15. 15. §  스프링과 하이버네이트를 이용한 게시판 만들기 §  Hibernate : ORM구현체중 하나(표준은 같이 구현은..) §  다운로드 §  스프링 §  http://www.springsource.org/ §  하이버네이트 §  http://hibernate.org/ §  아파치 커먼즈 로깅 §  http://commons.apache.org/logging/
  16. 16. §  배포 서술자 : 서블릿 어떻게 실행하느냐 정보 §  서블릿 등록 <servlet> <servlet-name>example</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
  17. 17. §  CORE는 꼭 필요하고 §  WEB와 WEB Servlet은 필요할 것 같고 §  그 다음에는 뭐가 필요 할까?
  18. 18. §  패키지 만들기 §  com.starpl.study §  컨트롤러 만들기 §  StudyController @RequestMapping(value = { "/hw.do" }, method = RequestMethod.GET) public String showMain(Model model) { model.addAttribute("data", "hello world"); return "/hw.jsp"; }
  19. 19. §  IoC 컨테이너 : applicationContext §  컨테이너가 코드 대신 오브젝트에 대한 제어권 가짐 §  리스너 : 환경이나 상태변화에 응답하는 클래스 §  리스너(컨텍스트 로드) 등록 <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
  20. 20. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.millky" /> <mvc:annotation-driven /> </beans>
  21. 21. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans> §  끝~ 수고하셨습니다! §  뭔가 엄청 힘든 이 느낌…
  22. 22. §  DB연동 : 하이버네이트 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.FactoryBean; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.ResourcePatternResolver; <context:component-scan base-package="com.starpl.study" /> §  §  §  hibernate3.jar hibernate-jpa-2.0-api-1.0.1.Final.jar jta-1.1.jar <mvc:annotation-driven /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/study?useUnicode=true&amp;characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="1q2w" /> <!-- 커넥션 풀을 유지해보자. --> <property name="maxActive" value="10" /> <property name="maxIdle" value="5" /> <property name="maxWait" value="20000" /> <property name="logAbandoned" value="true" /> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="60" /> <property name="testOnBorrow" value="true" /> <property name="testOnReturn" value="true" /> <property name="validationQuery" value="SELECT 1" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> §  slf4j-api-1.6.1.jar §  dom4j-1.6.1.jar §  §  §  javassist-3.12.0.GA.jar commons-collections-3.1.jar org.springframework.jdbc-3.0.6.RELEASE.jar <property name="namingStrategy"> <bean class="org.hibernate.cfg.ImprovedNamingStrategy" /> </property> <property name="annotatedClasses"> <bean class="com.starpl.study.EntityBeanFinderFactoryBean"></bean> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.use_sql_comments">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="eventListeners"> <map> <entry key="merge"> <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener" /> </entry> </map> </property> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> </beans> /** * <pre> * This class finds all @Entity annotated classes defined by an ANT style class name pattern. * Default pattern is **.entity.** * </pre> * * @author marcus.bristav@dreampark.com * @version 1.1 edit by byuri */ public class EntityBeanFinderFactoryBean implements ResourceLoaderAware, FactoryBean<Object> { private ResourcePatternResolver resolver; @SuppressWarnings("rawtypes") private List<Class> managedClasses = null; private String classPattern = "classpath*:**/entity/**/*.class"; static final int UTF = 1, INTEGER = 3, FLOAT = 4, LONG = 5, DOUBLE = 6, CLASS = 7, STRING = 8, FIELD_REF = 9, METHOD_REF = 10, INTERFACE_METHOD_REF = 11, NAME_AND_TYPE = 12; @Override public void setResourceLoader(ResourceLoader resourceLoader) { resolver = (ResourcePatternResolver) resourceLoader; } @Override public Object getObject() throws Exception { if (managedClasses == null) { loadManagedClasses(); } return managedClasses; } @Override public Class<? extends Object> getObjectType() { return List.class; } @Override public boolean isSingleton() { return true; } @SuppressWarnings("rawtypes") private void loadManagedClasses() throws Exception { managedClasses = new ArrayList<Class>(); Resource[] resources = resolver.getResources(classPattern); if (resources != null) { for (Resource res : resources) { Class<? extends Object> klass = getClass(res); if (hasEntityAnnotation(klass)) { managedClasses.add(klass); } } } } private Class<? extends Object> getClass(Resource res) throws Exception §  org.springframework.orm-3.0.6.RELEASE.jar §  org.springframework.transaction-3.0.6.RELEASE.jar §  DBCP §  §  http://commons.apache.org/dbcp/ http://commons.apache.org/pool/ { String className = className(res); return Class.forName(className); } private boolean hasEntityAnnotation(Class<?> klass) { return (klass.getAnnotation(javax.persistence.Entity.class) != null); } private String className(Resource res) throws Exception { InputStream is = res.getInputStream(); Map<Integer, Integer> offsetTable = new HashMap<Integer, Integer>(); Map<Integer, String> classNameTable = new HashMap<Integer, String>(); DataInputStream data = new DataInputStream(new BufferedInputStream(is)); int constant_pool_count = data.readShort(); for (int i = 1; i < constant_pool_count; i++) { int tag = data.read(); switch (tag) { case CLASS: int offset = data.readShort(); offsetTable.put(i, offset); break; case UTF: int length = data.readShort(); char[] bytes = new char[length]; for (int k = 0; k < bytes.length; k++) { bytes[k] = (char) data.read(); } String className = new String(bytes); classNameTable.put(i, className); break; case LONG: case DOUBLE: data.readLong(); i++; break; case STRING: data.readShort(); break; default: data.readInt(); } } int this_class = data.readShort(); String thisClassName = classNameTable.get(offsetTable.get(this_class)); is.close(); return thisClassName.replace("/", "."); } }
  23. 23. package com.starpl.study.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "test") public class Test { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "idx") private int idx; // PK, 자동생성 @Column(name = "subject", length = 500) private String subject; //getter, setter }
  24. 24. package com.starpl.study.dao; import java.util.List; import com.starpl.study.entity.Test; public interface TestDao { /** * 리스트를 가지고 온다 */ List<Test> getTestList(); package com.starpl.study.dao; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Restrictions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; import com.starpl.study.entity.Test; @Repository public class TestDaoImpl implements TestDao { @Autowired private HibernateTemplate hibernateTemplate; @Override public List<Test> getTestList() { @SuppressWarnings("unchecked") List<Test> testList = (List<Test>) this.hibernateTemplate.execute(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) { Criteria criteria = session.createCriteria(Test.class); return criteria.uniqueResult(); /** * 글 작성 */ boolean insertTest(Test test); } }); return testList; } @Override public boolean insertTest(Test test) { this.hibernateTemplate.save(test); return true; } @Override /** * 글 수정 */ boolean updateTest(Test test); public boolean updateTest(final Test test) { this.hibernateTemplate.execute(new HibernateCallback<Object>() { @Override public Object doInHibernate(Session session) { Criteria criteria = session.createCriteria(Test.class); criteria.add(Restrictions.eq("idx", test.getIdx())); return criteria.uniqueResult(); } } }); this.hibernateTemplate.update(test); return true; } }
  25. 25. @Autowired private TestDao testDao; @RequestMapping(value = { "/list.do" }, method = RequestMethod.GET) public String showJoinForm(Model model) { List<Test> testList = testDao.getTestList(); for (Test test : testList) { System.out.println(test.getSubject()); } model.addAttribute("testList", testList); model.addAttribute("data", "hello world"); return "/hw.jsp"; }
  26. 26. §  JSTL §  http://jstl.java.net/ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:forEach var="item" items="${testList}" varStatus="status"> ${item.idx} ${item.subject} </c:forEach>
  27. 27. §  맞습니다 §  더 어렵습니다 §  하지만 확장을 하려 한다면??? §  지금부터 게시판에 작성일시을 넣어보세요~ §  다국어를 지원해 주세요~, 로그를 남겨주세요~.. §  모델 1 개발자 : 아… ㅅㅂ §  모델 2 개발자 : 데모시간 안에는 끝나겠지 ㅇㅇ
  28. 28. §  Entity §  private java.util.Date regDate; §  DAO §  test.setRegDate(Calendar.getInstance().getTime()); §  View §  <%@ taglib prefix="fmt” uri="http://java.sun.com/jsp/jstl/fmt"%> §  <fmt:formatDate value="${item.regDate}” pattern="yyyy.MM.dd (E) HH:mm" />
  29. 29. §  결론 : 자바 웹 개발은 ( )다! §  자바 웹 개발 환경 구축은 10분이면 된다 §  모델1, 모델2(스프링@MVC)의 차이를 이해했다 §  모델 2를 사용하니 유지보수가 쉽다 §  과제 1 : 직접 개발 환경을 구성해 오세요(OS 무관) §  과제 2 : M2 게시판에 삭제 기능을 추가해 오세요

×