글쓰기 부분입니다.

얘는 Form이 들어가서 살짝 복잡합니다-_-;












writeController를 보도록 합시다.
[code]
<bean id="guestbookWriteValidator"
  class="com.mudchobo.guestbook.logic.GuestbookWriteValidator" />
 
<bean id="writeController"
  class="com.mudchobo.guestbook.controller.WriteController">
  <property name="sessionForm" value="true" />
  <property name="commandName" value="guestbookWrite" />
  <property name="commandClass"
    value="com.mudchobo.guestbook.logic.GuestbookWrite" />
  <property name="validator" ref="guestbookWriteValidator" />
  <property name="formView" value="list" />
  <property name="successView" value="list.do" />
  <property name="guestbookManager">
   <ref bean="guestbookMan" />
  </property>
</bean>
[/code]
writeController를 보면 여러가지 property가 있습니다. 사실......-_-; 잘 모르겠습니다-_-;
commandClass는 GuestbookWrite클래스를 값으로 사용하는데 이 클래스는 지금 현재 폼에 input이 3개가 있습니다. 이름, 제목, 내용. 이 3가지를 GuestbookWrite라는 VO에 담으려고 쓰는 것 같습니다.
그리고 validator는 guestbookWriteValidator를 참조했는데 이것은 GuestbookWriteValidator라는 클래스입니다. 이걸 Validator로 쓰겠다는 겁니다. 이것은 값을 받았을 때 해당 폼의 input의 값이 ""이면 에러를 추가하도록 되어있습니다. 사실 이부분 구현하다 말았습니다-_-;(귀차나서-_-)

formView는 list, list.jsp를 말하는 것 같습니다. successView는 성공시에 list.do를 수행하라는 겁니다.
guestbookManager는 Manager클래스를 참조합니다. 참조해서 데이터를 넣어야 하기 때문이죠 ^^

자 이제 실질적으로 하는 Controller를 보도록 합시다.
[code]
protected ModelAndView onSubmit(HttpServletRequest request,
   HttpServletResponse response, Object command, BindException errors)
   throws Exception {
  GuestbookVO guestbookVO = new GuestbookVO();
 
  guestbookVO.setName(((GuestbookWrite)command).getName());
  guestbookVO.setSubject(((GuestbookWrite)command).getSubject());
  guestbookVO.setContent(((GuestbookWrite)command).getContent());
  guestbookVO.setIp(request.getRemoteAddr());
  guestbookVO.setDatetime(new Timestamp(System.currentTimeMillis()));
 
  guestbookManager.writeGuestbook(guestbookVO);
 
  return new ModelAndView(new RedirectView(getSuccessView()));
 }
[/code]
우선 form액션을 수행하는 Controller는 SimpleFormController를 상속받아요. onSubmit메소드를 오버라이드합니다. 폼을 채우고 글쓰기버튼을 눌렀을 때 write.do를 수행하는데 그것을 수행하게 되면 writeController를 수행합니다.
command를 GuestbookWrite형으로 형변환하는군요. 아....위에 commandClass가 이건거 같군요.
저렇게 하니까 getName 등의 getter를 사용할 수 있군요.
그것을 가져와서 guestbookVO setter에 넣습니다. ip주소나 시간은 따로 생성합니다.
writeGuestbook메소드를 호출하니 그냥 끝나는군요.
writeGuestbook메소드를 보도록합시다.
[code]
public void writeGuestbook(GuestbookVO guestbookVO) {
  jdbcTemplate = new JdbcTemplate(dataSource);
  String query = "INSERT INTO guestbook (name, subject, content, ip, datetime) " +
      "VALUES (?, ?, ?, ?, ?)";
 
  Object[] params = new Object[] { guestbookVO.getName(),
          guestbookVO.getSubject(),
          guestbookVO.getContent(),
          guestbookVO.getIp(),
          guestbookVO.getDatetime() };
 
  jdbcTemplate.update(query, params);
 }
[/code]
insert 쿼리를 만들고 5가지의 ?를 넣었네요. 거기에 Object를 생성해서 각각의 값을 불러와서 넣어주고 가볍게
update한번하니 끝나네요. 와 간단해요!

아.....아무도 안볼꺼지만 그래도 그나마 저의 삽질이 도움이 되시는 분이 한분이라도 계셨으면 좋겠네요 ^^

 
Posted by 머드초보

댓글을 달아 주세요

  1. 초보자 2008.03.07 15:14  댓글주소  수정/삭제  댓글쓰기

    프레임웍 초보입니다. 덕분에 많은 도움이 되었습니다. 고맙습니다. ^^)/

    • 머드초보 2008.03.07 19:28  댓글주소  수정/삭제

      좀 오래된 예제를 보고 만든거라 잘못된게 좀 많을 껍니다-_-;
      그래도 도움이 되셨다니 다행이네요 ^^

  2. 무지초보 2008.10.30 09:31  댓글주소  수정/삭제  댓글쓰기

    좋은정보 너무 감사드립니다.
    질문이 있는데.. java.lang.LinkageError : << 이런 애러가 났는데 뭔지 모르겠네요 ㅠ

    • 머드초보 2008.10.31 10:06  댓글주소  수정/삭제

      처음 보는 에러인데요.
      검색해보니 jdk의 경로가 잘못 잡혀있어서 그런 듯 합니다.
      구글신께 물어보시는 게 더 빠를듯합니다 ㅠㅠ

 



확실히 db연동부분은 쉽군요-_-; try catch도 안해도 되고, 커넥션 같은것도 스프링에서 다 알아서 해줘요-_-;
처음 틀만 제대로 만들어놓으면 개발하는데에는 더 속도가 빨라질 것 같아요.









우선 ListController클래스를 봅시다.
[code]
List<GuestbookVO> contentslist = getGuestbookManager().getContents();  
return new ModelAndView("list", "contentslist", contentslist);
[/code]
멤버변수로 있는 guestbookManager는 springapp-servlet.xml에서 알아서 셋팅되니 우리는 그냥 getter만 하면 됩니다. 가져와서 getContents()메소드를 호출하면 List를 다 가져오는 메소드입니다.

자세히 보도록 합시다.
GuestbookManagerDao클래스는 인터페이스입니다. GuestbookManagerDaoJdbc클래스는 저 인터페이스를 구현해 놓은 클래스입니다.
getContents()메소드
[code]
@SuppressWarnings("unchecked")
public List<GuestbookVO> getContents() {
 
  jdbcTemplate = new JdbcTemplate(dataSource);
  String query =
  "SELECT no, name, subject, content, ip, datetime FROM guestbook ORDER BY no DESC";
 
  List<GuestbookVO> contentslist =
                   (List<GuestbookVO>)jdbcTemplate.queryForList(query);
 
  return contentslist;
 }
[/code]
코드를 보니 예전에 스트럿츠에서하던 try-catch-finally는 다 걷어버리고, 딸랑 몇개만 남았어요. 커넥션하는것도 없어요-_-; 매우 간단해요!-_-;
아....참고로 저렇게 해도 나쁜방식입니다. 원래는 하나하나 매핑해줘야한다더군요.(이것도 아이군한테 혼났어요-_-;)
dataSource는 xml에서 다 해주니 새로운 jdbcTemplate을 생성합니다. 이 생성된 jdbcTemplate이 제공하는 메소드중에 queryForList라는게 있는데 query를 주면 자동으로 List형태로 반환해주는 메소드입니다.
저렇게 리스트 형식으로 받게 됩니다. 자동으로 가져오는 것보다 매퍼라는게 있는데 그걸로 매핑해서 하는게 명확한 표현입니다.
아 그리고 저렇게하면 워링이 뜨는데 그건 프레임워크에서 만들어진 List형에 아무것도 안붙어있기때문이죠.
jdk1.5.0이상부터는 List에는 형태를 명시해주기로 되어있어요. ex) List<GuestbookVO>
가볍게 무시를 해줍시다-_-;
이클립스에서 해주는데 @SuppressWarnings("unchecked") 라고하면 워링이 사라집니다.

이제 Controller는 이 List를 받아서 list.jsp을 요청하면 List를 넘겨줍니다.
list.jsp를 봅시다.
[code]
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><fmt:message key="title"/></title>
</head>
<body>

<form action="write.do" method="post">

이름 : <input name="name" type="text"/>
제목 : <input name="subject" type="text"/><br />
내용 : <br /><textarea name="content" rows="10" cols="50"></textarea><br />
<br />
<input type="submit" value="글쓰기"/>
<br />
<spring:hasBindErrors name="guestbookWrite">
 <b>필드를 채워주세요!</b>
</spring:hasBindErrors>
<hr />
</form>
<c:forEach var="contentslist" items="${contentslist}">
 <div>
 <p>이름 : ${contentslist.name}</p>
 <p>제목 : ${contentslist.subject}</p>
 <p>내용 : ${contentslist.content}</p>
 <p>아이피 : ${contentslist.ip}</p>
 <p>날짜 : ${contentslist.datetime}</p>
 </div>
 <hr />
</c:forEach>

</body>
</html>
[/code]
spring태그는 우선 가볍게 무시합시다. 위에 쓰기위한 폼이 있고, 아래에는 forEach를 통해 반복하고 있군요.
list.jsp에 딸려온 contentslist에 있는 것을 반복해서 출력해줍니다.
저거 el표기법인데 구글에서 가볍게 검색해서 공부해봅시다(사실 저도 잘 모릅니다-_-;)
jstl도 가볍게 검색해주고-_-;

방명록소스
http://mudchobo.tomeii.com/tt/120
 
Posted by 머드초보

댓글을 달아 주세요

 

아....-_-;

우선 소스부분
com.mudchobo.guestbook.common - 공통부분이라는 뜻인데 뭐 그냥 인코딩필터밖에 없어요. UTF-8로 인코딩한다 뭐 그런내용밖에-_-; 저도 친구가 쓰는거 가져다가 그냥 썼습니다.

com.mudchobo.guestbook.controller - 말그대로 MVC 중에 Controller에 관련된 클래스가 있습니다.

com.mudchobo.guestbook.db - db와 연동하는 dao클래스가 있습니다.

com.mudchobo.guestbook.logic - 로직과 폼에 관련된 클래스가 있습니다.

com.mudchobo.guestbook.vo - Value Object 클래스가 있습니다.

WEB-INF에는 web.xml과 springapp-servlet.xml, spring.tld가 있습니다.

WEB-INF/jsp에는 jsp 가 있습니다-_-;

우선 web.xml을 봅시다.
[code]
<servlet>
   <servlet-name>springapp</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
 
<servlet-mapping>
   <servlet-name>springapp</servlet-name>
   <url-pattern>*.do</url-pattern>
</servlet-mapping>
[/code]
서블릿을 스프링프레임워크에서 제공하는 DispatcherServlet을 사용합니다. 이것은 *.do으로 들어오는 요청에 대해서는 이 서블릿으로 처리한다는 뜻입니다.

자 이제 가장 중요한 bean들을 모아둔 springapp-servlet.xml을 보도록 합시다.
(파일이름이 서블릿이름-servlet.xml으로 짓는걸 권장하는데 요즘에는 이렇게 안쓰는거 같아요. xml도 분할하고 그러는 것 같습니다.)
[code]
<beans>

 <bean id="springappController"
   class="com.mudchobo.guestbook.controller.SpringappController" />
 
 <bean id="listController"
   class="com.mudchobo.guestbook.controller.ListController">
  <property name="guestbookManager">
   <ref bean="guestbookMan" />
  </property>
 </bean>
 
 <bean id="guestbookWriteValidator"
  class="com.mudchobo.guestbook.logic.GuestbookWriteValidator" />
 
 <bean id="writeController"
  class="com.mudchobo.guestbook.controller.WriteController">
  <property name="sessionForm" value="true" />
  <property name="commandName" value="guestbookWrite" />
  <property name="commandClass"
    value="com.mudchobo.guestbook.logic.GuestbookWrite" />
  <property name="validator" ref="guestbookWriteValidator" />
  <property name="formView" value="list" />
  <property name="successView" value="list.do" />
  <property name="guestbookManager">
   <ref bean="guestbookMan" />
  </property>
 </bean>
 
 <bean id="dataSource"
   class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
<value>com.mysql.jdbc.Driver</value></property>
  <property name="url">
   <value>db주소</value>
  </property>
  <property name="username"><value>dbid</value></property>
  <property name="password"><value>dbpw</value></property>
 </bean>
 
 <bean id="guestbookManDao"
   class="com.mudchobo.guestbook.db.GuestbookManagerDaoJdbc">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean>
 
 <bean id="guestbookMan"
   class="com.mudchobo.guestbook.logic.GuestbookManager">
  <property name="guestbookManagerDao">
   <ref bean="guestbookManDao" />
  </property>
 </bean>
 
 <bean id="urlMapping"
   class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/index.do">springappController</prop>
    <prop key="/list.do">listController</prop>
    <prop key="/write.do">writeController</prop>
    <!--
    <prop key="/delete.htm">DeleteFormController</prop>
     -->
   </props>
  </property>
 </bean>
 
 <bean id="viewResolver"
   class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass">
   <value>org.springframework.web.servlet.view.JstlView</value>
  </property>  
  <property name="prefix">
   <value>/WEB-INF/jsp/</value>
  </property>
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>
 
 <bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basename"><value>messages</value></property>
 </bean>
</beans>
[/code]
우선 urlMapping bean을 봅시다. list.do 요청이 들어오면 listController빈을 수행합니다. listController는 ListController클래스입니다. 이 클래스의 property는 guestbookManager입니다. 이것은 ListController클래스의 멤버변수를 의미합니다. 이 xml에서 이 해당 멤버변수값을 참조할 수 있습니다. 보시면 알겠지만, ref태그를 통해서 bean을 참조합니다. guestbookMan 빈을 가져올 수 있는 것입니다.
뭐 이런식으로 구조가 되어있어요. ListController는 GuestbookManager클래스를 가져와서 저 Manager클래스는 getContents()등 실제 로직이 있는 클래스이므로 저 메소드를 호출해서 List를 가져올 수 있는 것입니다.
Manager클래스는 Dao를 참조해서 데이터를 가져옵니다.

이런식의 구조로 되어있습니다-_-;

db테이블은
[code]
CREATE TABLE `guestbook` (
  `no` int(11) NOT NULL auto_increment,
  `name` varchar(250) default NULL,
  `subject` varchar(2000) default NULL,
  `content` text,
  `ip` varchar(15) default NULL,
  `datetime` datetime default NULL,
  PRIMARY KEY  (`no`)
) ENGINE=MyISAM  DEFAULT CHARSET=euckr AUTO_INCREMENT=23 ;
[/code]
입니다.

방명록소스
http://mudchobo.tomeii.com/tt/120
 
 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon Mesothelioma Lawyer 2011.08.10 13:37  댓글주소  수정/삭제  댓글쓰기

    Your blog is very useful. Thank you so much for providing plenty of useful content. I have bookmarked your blog site and will be without doubt coming back. Once again, I appreciate all your work and also providing a lot vital tricks for your readers.

 
초를 5개 붙인 이유는 오로지 글쓰기랑 리스트보기밖에 안돼요-_-;
최근 귀차니즘의 향상으로-_-; 스프링의 동작원리를 파악하기 위해 제작했는데 이정도로 대충만들줄은...-_-;

TEXTAREA에서 줄바꿈도 안되고요-_-; 이거 메소드만 하나 넣어주면 되는데 ^^

뭐 가장 중요한건 뭐 어떻게 돌아가는냐가 중요하니 ^^ 공부하다가 삽질한거 올려요
ORM같은거는 뭐 사용할 줄 몰라서 스프링에 있는거 그냥 썼는데 제대로 쓴건지 모르겠어요.

아.....옛날 문서보고 하다가 친구한테 또 욕먹었어요-_-;
뭐 어쨌든 DB연동 부분에서는 스프링이 확실히 편한 거 같군요.

예제 주소입니다.
http://mudchobo.tomeii.com/SpringGuestBook/

설명은 나중에-_-; 일해야해요-_-;


SpringGuestBook.war

방명록아닌방명록 소스(war)

 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon 아이 2007.10.02 13:53  댓글주소  수정/삭제  댓글쓰기

    ㅊㅋㅊㅋ

 

아.....제가 제일 좋아하는 헬로우 월드 찍는 시간입니다--;

이번에는 스프링 프레임워크를 이용해서 해봅시다. 계속 삽질중인데 이제 좀 이해가 가려고해요-_-;

JDK1.6.0 + TOMCAT 6.0 + SpringFramework 2.0.6에서 작업했습니다. 다 6이 들어가는군요-_-;

우선 스프링 프레임워크를 받아봅시다. 최신버전이 2.0.6 이군요.
spring-framework-2.0.6-with-dependencies 파일입니다.
http://www.springframework.org/download

이제 보기도 지겨운 보라색에 세줄그어진 이클립스라는 놈을 열어봅시다-_-;

File -> New -> 아래꺼Project 클릭후 Dynamic Web Project 선택.
프로젝트 이름은 SpringHelloWorld 라고 합시다.
Target Runtime은 Tomcat으로 하고 Finish를 합시다..

lib폴더에 lib파일들을 넣어야합니다.
스프링 받은거 압축을 풀면
spring-framework-2.0.6\dist\spring.jar파일(스프링 프레임워크 lib파일)
spring-framework-2.0.6\lib\jakarta-commons\commons-logging.jar파일(로그사용을 위한 lib파일)

http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi
여기서 태그라이브러리 사용을 위한 jar파일을 받습니다.
standard.jar와 jstl.jar파일이 있습니다(태그라이브러리를 위한 lib파일)

4개파일을 lib폴더에 집어넣습니다.

web.xml파일을 수정합시다.
[code]
<display-name>SpringHelloWorld</display-name>
 
  <servlet>
    <servlet-name>springapp</servlet-name>
    <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
  </servlet>
 
  <servlet-mapping>
   <servlet-name>springapp</servlet-name>
   <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
[/code]
*.htm으로 들어오는 요청에 대해서는 springapp서블릿을 사용하겠다는 얘기네요. 서블릿은 스프링프레임워크에 있는 DispatcherServlet이랍니다

DispatcherServlet의 제어 행위를 처리하는 설정 파일이 필요한데, 이것은 서블릿 이름에 -servlet.xml을 붙여서 작성합니다.
/WEB-INF/springapp-servlet.xml을 작성해봅시다.
[code]
<beans>
 <bean id="springappController" class="web.SpringappController" />
 
 <bean id="urlMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/hello.htm">springappController</prop>
   </props>
  </property>
 </bean>
 
 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass">
   <value>org.springframework.web.servlet.view.JstlView</value>
  </property>
  <property name="prefix">
   <value>/WEB-INF/jsp/</value>
  </property>
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>
 
</beans>
[/code]
대충 보아하니 beans태그 안에 bean태그가 3개가 있네요. 첫번째꺼는 Controller이고, 두번째꺼는 urlMapping시켜주는데 /hello.htm으로 요청이 들어오면 springappController에게 넘기라는 걸로 보이는군요-_-;
세번째꺼는 선행자와 후위자를 정해놓는 뭐그런거 같습니다. 미리 써놓으면 항상 쓰이는 WEB-INF/jsp/파일이름.jsp 에서 앞 뒤 없이 이름만 써도 되니까요.

SpringappController.java를 작성해봅시다.
이놈은 Controller라는 인터페이스를 상속받습니다.
web이라는 패키지를 생성후 거기에다가 class를 생성합니다.
생성할 때 New Java Class화면에서 Interface부분에 Add버튼을 클릭해서 Controller를 선택해서 추가해주면 자동으로 해줍니다.
[code]
package web;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class SpringappController implements Controller {

 protected final Log logger = LogFactory.getLog(getClass());
 
 public ModelAndView handleRequest(HttpServletRequest arg0,
   HttpServletResponse arg1) throws Exception {
        String now = (new Date()).toString();
        logger.info("returning hello view with " + now);
 
        return new ModelAndView("hello", "now", now);
    }
}
[/code]
그냥 시간을 리턴합니다. new Date()로 시간을 생성해서 그걸 String으로 변환해서 now변수에 넣고, 로그를 기록하고, return할 때 now라는 변수는 now라는 이름으로 쓸 수 있게 hello파일에 넘겨줍니다. 이 hello는 앞 뒤 합치면 /WEB-INF/hello.jsp 가 되는 겁니다.

이제 /WEB-INF/hello.jsp파일을 봅시다.
[code]
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Hello :: Spring Application</title>
</head>
<body>
<h1>Hello World! - Spring Application</h1>
<p>Greetings, it is now<c:out value="${now}" /></p>
</body>
</html>
[/code]
now라는 변수를 c:out태그로 출력합니다. Controller에서 시간을 담아서 넘겨줬습니다.
아 그리고 jsp파일을 WEB-INF폴더에 넣는 이유는 JSP파일 접근에 대한 권한이 아마 우리한테 없고 SPRING에게 넘겨서 일껍니다-_-; 즉 직접적으로 접근하지 못하도록 하려고....-_-; 그런거 같습니다 ^^

was/SpringHelloWorld로 접속시 index.jsp를 실행하는데 없으니 하나 만듭시다.
index.jsp
<script>
location.href="hello.htm"
</script>
바로 hello.htm으로 포워드해줍니다-_-; 자 그럼 실행해봅시다.

사용자 삽입 이미지


다음번엔 게시판이나 한번 만들어봐야겠어요-_-;

 
Posted by 머드초보

댓글을 달아 주세요

  1. HJ. 2008.07.14 20:14  댓글주소  수정/삭제  댓글쓰기

    spring.jar 에 말고 spring-webmvc.jar 안에 servlet파일들이 들어있네요.
    spring.jar 파일만 사용하면 에러가 나더라구요.

  2. HJ. 2008.07.15 11:31  댓글주소  수정/삭제  댓글쓰기

    참참- 이말을 잊었네요.
    "감사합니다~~ 완전 초본데ㅜㅜ 좋은 공부됐습니다^^"

    • 머드초보 2008.07.15 18:24  댓글주소  수정/삭제

      앗! 도움이 되셨다니 다행입니다 ^^
      저도 아직 초보라 삽질의 끝을 향하여 계속 파고 있습니다 ^^
      같이 열심히 파요 ^^