Upload
dk-lee
View
537
Download
3
Embed Size (px)
DESCRIPTION
Java web development 01 자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습) 2011. 10. 26 벌써 2년도 넘은 자료지만 그래도 필요하신분이 있을지 몰라서... (지금보니 2년사이 많은것을 배운것 같네요 ㅎㅎ)
Citation preview
자바 웹 개발 시작하기 (1주차 : 웹 어플리케이션 체험 실습)
2011. 10. 26
DEVELOPMENT #2
이덕곤
§ 환경구축 Hello, world 데모 순서 (약 30분) § VirtualBox 다운로드 및 설치
§ WindowsXP 설치 (빵집 다운로드 및 설치)
§ JDK 다운로드 및 설치
§ Tomcat 다운로드 및 설치
§ Eclipse 다운로드 및 설치 (Java폴더 만들어서)
§ UTF-8 설정
§ 서버 만들기
§ JSP파일 만들어서 Hello, world! 출력하기
§ 환경구축 어렵다는 말은 옛말(물론 서비스용은..) § 윈도설치시간 다운로드시간 제외하면 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/
§ 사실 거의 모든 웹 개발은 게시판 개발 (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
§ 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;
§ JSP가 모든 것을 처리
Web Browser
웹컨테이너
httpd HTML
JSP (빈즈호출)
JSP (결과뷰어)
BANS
DB
①요청 ②HTML인 경우
③JSP인경우
⑥다음 JSP호출
④<JSP:useBean../> ⑤DB처리
⑦<JSP:useBean../>
웹 컨테이너
웹 서버
JSP
모든 것을 처리하는 슈퍼 울트라 캡송 JSP
<% … %>
§ 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();
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){}
}
§ 목록보기 쿼리 String query = "select * from test order by idx desc";
§ 쿼리 실행
rs = stmt.executeQuery(query);
while(rs.next()) {
<%= rs.getString("idx") %>
<%= rs.getString("subject") %>
}
§ 글 쓰기 쿼리 String query = "insert into test (subject) value ('"+ subject +"')";
§ 글 수정 쿼리 String query = "update test set subject = '"+ subject +"' "
+ ”where idx = '"+idx+"'";
§ 쿼리 실행 int count = stmt.executeUpdate(query); // 리턴값은 실행 수
§ 페이지에 대한 클래스 정보 <%@ page contentType = "text/html; charset=UTF-8" %>
<%@ page pageEncoding = "UTF-8" %>
<%@ page import = "java.sql.*" %>
§ 완료 후 처리
<% if(count > 0) { %>
<% response.sendRedirect("/"); %>
<% } else { %>에러<% } %>
§ MVC모델로 나누어 처리
Web Browser
웹컨테이너
httpd HTML
<<Controller>> Servlet or JSP
<<View>>
JSP <<DAO>>
클래스
DB
①요청 ②HTML인 경우
③JSP인경우
⑦적절한 View로 포워딩
④<JSP:useBean../>
⑥ DB 접속 및 처리
웹 컨테이너
웹 서버
<<View>>
JSP
<<Model>> 빈즈
⑤DAO 클래스 사용
§ 핵심은 DispatcherServlet
§ 스프링 및 기타 프레임워크로 구성
개발 : Eclipse 3.7.1 (SVN : 버전관리, Log4j : 로그)
Java SE 6 update X Java EE 5
Tomcat 6.0.XX (Servlet 2.5, JSP 2.1)
Spring MVC : WEB (컨트롤 부분)
2.3 DAO (모델 부분)
MySQL Connector For Java 5.1.XX
JSP 2.0(JSTL 1.1, EL) (뷰 부분)
5.1.XX
POJO Bean : Domain, Service (비즈니스 부분)
§ 스프링과 하이버네이트를 이용한 게시판 만들기 § Hibernate : ORM구현체중 하나(표준은 같이 구현은..)
§ 다운로드
§ 스프링 § http://www.springsource.org/
§ 하이버네이트 § http://hibernate.org/
§ 아파치 커먼즈 로깅 § http://commons.apache.org/logging/
§ 배포 서술자 : 서블릿 어떻게 실행하느냐 정보
§ 서블릿 등록 <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>
§ CORE는 꼭 필요하고
§ WEB와 WEB Servlet은 필요할 것 같고
§ 그 다음에는 뭐가 필요 할까?
§ 패키지 만들기 § com.starpl.study
§ 컨트롤러 만들기
§ StudyController @RequestMapping(value = { "/hw.do" }, method = RequestMethod.GET)
public String showMain(Model model)
{
model.addAttribute("data", "hello world");
return "/hw.jsp";
}
§ IoC 컨테이너 : applicationContext § 컨테이너가 코드 대신 오브젝트에 대한 제어권 가짐
§ 리스너 : 환경이나 상태변화에 응답하는 클래스
§ 리스너(컨텍스트 로드) 등록 <listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<?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>
<?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>
§ 끝~ 수고하셨습니다!
§ 뭔가 엄청 힘든 이 느낌…
§ DB연동 : 하이버네이트 § hibernate3.jar
§ hibernate-jpa-2.0-api-1.0.1.Final.jar
§ jta-1.1.jar
§ 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
§ 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/
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; /** * <pre> * This class finds all @Entity annotated classes defined by an ANT style class name pattern. * Default pattern is **.entity.** * </pre> * * @author [email protected] * @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 { 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("/", "."); } }
<?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.starpl.study" /> <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&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" /> <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>
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
}
package com.starpl.study.dao; import java.util.List; import com.starpl.study.entity.Test; public interface TestDao {
/** * 리스트를 가지고 온다 */ List<Test> getTestList();
/** * 글 작성 */ boolean insertTest(Test test);
/** * 글 수정 */ boolean updateTest(Test test);
}
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(); } }); return testList; }
@Override public boolean insertTest(Test test) { this.hibernateTemplate.save(test); return true; }
@Override 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; }
}
@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";
}
§ 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>
§ 맞습니다
§ 더 어렵습니다
§ 하지만 확장을 하려 한다면???
§ 지금부터 게시판에 작성일시을 넣어보세요~
§ 다국어를 지원해 주세요~, 로그를 남겨주세요~..
§ 모델 1 개발자 : 아… ㅅㅂ
§ 모델 2 개발자 : 데모시간 안에는 끝나겠지 ㅇㅇ
§ 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" />
§ 결론 : 자바 웹 개발은 ( )다!
§ 자바 웹 개발 환경 구축은 10분이면 된다
§ 모델1, 모델2(스프링@MVC)의 차이를 이해했다
§ 모델 2를 사용하니 유지보수가 쉽다
§ 과제 1 : 직접 개발 환경을 구성해 오세요(OS 무관)
§ 과제 2 : M2 게시판에 삭제 기능을 추가해 오세요