전시간에 이어서.....
이걸 좀 수정해봅시다.

우선 List를 받으려면 idx, 제목, 글쓴이의 정보가 필요합니다. 하지만, 기본적인 RESTful 웹서비스를 생성하게 되면 idx밖에 반환하지 않습니다. 이걸 고쳐봅시다.

boarddb.converter패키지에 WsboardsConverter클래스가 있습니다.
클래스 위에 XmlRootElement(name = "wsboards")라는 것이 붙어있습니다. 그렇습니다. 클래스형태가 바로 애노테이션 하나로 xml이 되버립니다-_-;(동작원리는 잘 모르겠네요-_-)
현재 데이터를 이런 식으로 반환합니다.
[code]<wsboards uri="http://localhost:9080/BoardWS2/resources/wsboards/">
    <wsboardRef uri="http://localhost:9080/BoardWS2/resources/wsboards/33/">
        <idx>33</idx>
    </wsboardRef>
[/code]
여기에 subject와 writer를 추가해봅시다.
wsboardRef쪽에다가 추가를 해야하니, WsboardRefConverter클래스를 봅시다.
@XmlRootElement(name = "wsboardRef")가 붙어있습니다. @XmlElement애노테이션을 붙이면 Element를 생성할 수 있습니다.
[code]@XmlElement
public String getWriter() {
    return entity.getWriter();
}
@XmlElement
public String getSubject() {
    return entity.getSubject();
}
[/code]
이렇게 2개를 추가했습니다. 그리고 게시판은 최근글이 마지막에 보여야하므로 쿼리를 수정합니다.
WsboardsResource클래스의 getEntities메소드를 봅시다.
쿼리를 아래와같이 수정합니다.
[code]SELECT e FROM Wsboard e ORDER BY e.idx DESC"[/code]
다시 테스트를 해봅시다.
이제 이렇게 나올겁니다.
[code]<wsboardRef uri="http://localhost:9080/BoardWS2/resources/wsboards/33/">
      <idx>33</idx>
      <subject>111</subject>
    <writer>11</writer>
</wsboardRef>[/code]
와우 List는 이제 구현이 다되었습니다-_-;

List를 가져올 때 총 게시물을 뽑아서 나중에 페이징을 할 때 사용해야합니다. 총게시물을 구하는 쿼리는
[code]SELECT count(e) FROM Wsboard e[/code]
이렇게 하면 되더군요.
그럼 WsboardsResource.java파일의 @GET부분을 다음과 같이 바꿉시다.
[code]try {
    Long count = (Long)PersistenceService.getInstance().createQuery("SELECT count(e) FROM Wsboard e").getSingleResult();
    return new WsboardsConverter(getEntities(start, max), context.getAbsolutePath(), count);
} finally {
    PersistenceService.getInstance().close();
}
[/code]
카운트값을 xml에 표기를 해야하니 WsboardsConverter를 수정해야겠죠?
[code]
private Long count; // 추가
public WsboardsConverter(Collection<Wsboard> entities, URI uri, Long count) {
        this.entities = entities;
        this.uri = uri;
        this.count = count;
    }
[/code]
count변수를 추가하고, 생성자를 저렇게 생성하도록 바꿉니다.
속성값으로 count를 추가해야겠죠?
[code]
@XmlAttribute(name = "count")
    public String getCount() {
        return count.toString();
    }
[/code]

이제 1개데이터 가져오기를 구현해봅시다. 사실.....이건 다 되어있군요. Test RESTful Web Service에서 {idx}에서 해당 idx를 넣고 Test눌렀을 때 정상적으로 나오면 된겁니다 ^^

이제 DELETE와 MODIFY 2개가 남았습니다.
DELETE를 구현하기 위해서는 db에 저장된 비밀번호와 입력한 비밀번호의 비교를 위해서 비밀번호를 받는 것을 하나 추가합시다. 저는 그냥 경로에 추가했습니다. 보안상 매우 안좋지만...-_-; 어떻게 하는지 몰라서-_-;

WsboardsResource.java파일에서 @Path("{idx}/") -> @Path("{idx}/{pwd}")로 바꿨습니다.
그리고, 1개의 PathParam을 받았던 것을 pwd도 받게 바꿨습니다. 그리고 WsboardResource클래스에 pwd를 추가하고, 생성자를 수정했습니다.

WsboardsResource.java파일
[code]@Path("{idx}/{pwd}")
public WsboardResource getWsboardResource(@PathParam("idx")
Integer id, @PathParam("pwd") String pwd) {  
    return new WsboardResource(id, pwd, context);
}
[/code]
WsboardResource.java파일
[code]private String pwd; //추가
public WsboardResource(Integer id, String pwd, UriInfo context) {
    this.id = id;
    this.pwd = pwd;
    this.context = context;
} // 생성자 수정
[/code]
이제 /wsboards/{idx}/{pwd}로 요청하면 idx와 pwd를 받을 수 있습니다.

DELETE를 수정해봅시다.
[code]@DELETE
public Response delete() {
    PersistenceService persistenceSvc = PersistenceService.getInstance();
    try {
        Wsboard entity = getEntity();
        if (entity.getPwd().equals(pwd)) {               
            persistenceSvc.beginTx();
            persistenceSvc.removeEntity(entity);
            persistenceSvc.commitTx();
            return Response.ok("success").build();
        }
    } finally {
        persistenceSvc.close();
    }
    return Response.ok("fail").build();
}
[/code]
간단합니다. 받은 pwd랑 현재 입력된 pwd랑 같은지 확인 후에 맞으면 지우고 success를 리턴하고, 틀리면 fail을 리턴합니다. 테스트를 해볼 수 있는데요. 한번 지워보시면
[code]Delete failed: Server returned --> Status: (200) Response: {success}
[/code]저는 이런 메시지를 받습니다. Delete failed라고 뜨는데요. 그래도 success라는 응답을 받고 db에서 보면 지워졌을 겁니다. 보면 DELETE는 뭔가 리턴을 하면 안되는 듯 합니다. 암튼...잘 되니...-_-;

이제 PUT을 수정해봅시다.
[code]@PUT
@ConsumeMime({"application/xml", "application/json"})
public Response put(WsboardConverter data) {
    PersistenceService persistenceSvc = PersistenceService.getInstance();
    try {
        Wsboard entity = getEntity();
        if (entity.getPwd().equals(pwd)) {
            persistenceSvc.beginTx();
            updateEntity(getEntity(), data.getEntity());
            persistenceSvc.commitTx();
            return Response.ok("success").build();
        }
    } finally {
        persistenceSvc.close();
    }
    return Response.ok("fail").build();
}
[/code]
이것도 그냥 pwd랑 같으면 수정시키고 success를 리턴하고, 틀리면 수정 안시키고 fail을 리턴합니다.
테스트해봅시다.
테스트할 때 주의사항이....xml로 데이터를 던져야 하는데요. idx빼고 모든 값이 다 들어가야합니다.
PUT으로 맞춰놓고, idx랑 pwd를 쓴 다음 content란에 이렇게 씁니다.
[code]<wsboard>
<pwd>1</pwd>
<writer>11</writer>
<subject>22</subject>
<content>33</content>
</wsboard>
[/code]
idx빼고 다 넣어야합니다. 그러면 업데이트가 됩니다.

아....다 됐네요. 아.....POST로 글쓰는 것을 빼먹고 안했는데요. 그냥 위처럼 XML로 넘겨주기만 하면 돼요 ^^
flex로 게시판 만드는 것도 해야하는데, 졸려서 내일로.....-_-;

내일은 선테크데이2008가야지-_-;

[JAVA] netbeans 초간단 게시판을 위한 RESTful WebService를 만들어봅시다-_-; (1)


[Flex/AIR] RESTful을 이용한 Web Service 게시판 클라이언트.

 
Posted by 머드초보
,
 
우선 저도 잘 모르는 상태에서 삽질을 한거라....잘못된 점 있으면 바로바로 태클을 걸어주세요~

우선 리스트데이터 가져오기.
resources/wsboards/ 형태로 요청을 하면 데이터를 가져옵니다.
WebService로 넘겨줘야할 값은 start값과 max값을 넘겨줘서 값을 가져옵니다. method는 GET입니다.

1개 게시물데이터 가져오기.
이것은 url로 resource/wsboards/{idx}/ 하면 해당 idx에 맞는 데이터를 가져옵니다. method는 GET입니다.

게시물 쓰기
resources/wsboards/로 xml형태의 글쓴이, 제목, 내용, 비밀번호 등의 정보를 보내줍니다. method는 POST입니다.

게시물수정
resources/wsboards/{idx}/{pwd}로 xml형태의 글쓴이, 제목, 내용, 비밀번호 등의 정보를 보내서 {pwd}랑 맞으면 수정합니다. method는 PUT입니다.

게시물삭제
resources/wsboards/{idx}/{pwd}로 요청해 pwd랑 서버에 있는 데이터pwd랑 비교해서 맞으면 삭제합니다. method는 DELETE입니다.

요렇게 5가지만 있으면 되겠군요.

저는 NetBeans6.1 + GlassFish V2 + MySQL 5.0에서 했습니다 ^^
우선 DB를 만듭시다. MySQL을 실행해서 해당 wsboard 테이블을 만듭니다.
[code]DROP TABLE IF EXISTS `mudchobo`.`wsboard`;
CREATE TABLE  `mudchobo`.`wsboard` (
  `idx` int(10) unsigned NOT NULL auto_increment,
  `writer` varchar(10) NOT NULL default 'writer',
  `pwd` varchar(10) NOT NULL default 'pwd',
  `subject` varchar(50) NOT NULL default 'subject',
  `content` text,
  PRIMARY KEY  (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8;
[/code]

1. 넷빈즈6.1을 실행합니다.

2. New Project -> Web -> Web Application -> Project Name은 BoardWS로.....
서버는 GlassFish V2로 합니다. (tomcat으로 해도 되는데, 테스트가 용이하지 않아요!). Finish!

3. 해당프로젝트에 New -> Entity Classs from Database -> Data Source 선택, New Data Source -> JNDI Name에는 jndi/board, Database Connection에는 New Database Connection선택, Name을 MySQL로 바꿔주고, 알맞게 셋팅합니다 ^^ 그리고 확인을 누르면 해당 database에 있는 모든 테이블을 가져옵니다. 이중에 우리가 만든 wsboard테이블을 선택하고 add합니다 ^^
pakage는 boarddb라고 합시다. 아래 Create Persistence Unit를 선택해서 걍 다 디폴트로 주고 Create합니다. (이건 Unit을 자동으로 생성해주는 것 같더군요. 즉, 사용자가 직접 만들 수도 있죠. 아직 저는 JPA를 모르니..ㅠ) Finish!

해당 객체가 만들어졌습니다. 소스를 보게 되면
[code]@Id
@Column(name = "idx", nullable = false)
private Integer idx;
@Column(name = "writer", nullable = false)
private String writer;
@Column(name = "pwd", nullable = false)
private String pwd;
@Column(name = "subject", nullable = false)
private String subject;
@Lob
@Column(name = "content")
private String content;
[/code]
속성값을 Column이랑 애노테이션을 이용해서 자동으로 매핑해주는군요. MySQL의 text타입은 Lob(Large Object랍니다)으로 되는군요^^
이제 이것을 이용한 웹서비스를 만들어봅시다.

4. 프로젝트에 New -> RESTful Web Services from Entity Classes선택. 방금 추가했던 Wsboard클래스가 있습니다. add하고, Package만 boarddb.service, boarddb.converter로 바꾸고 Finish.

service클래스는 잘 보면 PersistenceService랑 WsboardResource, WsboardsResource 3가지가 있네요. PersistenceService는 말그대로 Persistence단에서 하는 db관련된 내용이구요. entity를 가져오거나, 추가, 삭제, 수정 등을 할 수 있는 클래스입니다.
WsboardsResource는 @Path("/wsboards/")가 클래스 앞에 붙어있는데요. 아마 저 해당 URL로 접근하면 이 클래스가 대신하는 것 같습니다. 이 클래스 메소드에 @GET, @POST가 있는데, 저 url로 저 메소드를 접근하게 되면 해당 메소드를 실행하는 역할을 하게 됩니다. Wsboard도 위와 비슷합니다 ^^

5. 프로젝트메뉴에 Test RESTful Web Services를 선택하면 브라우저가 뜨고, 테스트를 할 수 있습니다.

사용자 삽입 이미지

글이 길어지네-_-; 해당 웹서비스 수정은 다음시간에.....-_-;

[JAVA] netbeans 초간단 게시판을 위한 RESTful WebService를 만들어봅시다-_-; (2)


[Flex/AIR] RESTful을 이용한 Web Service 게시판 클라이언트.


참고자료 http://www.netbeans.org/kb/60/websvc/rest-mysql.html
 
Posted by 머드초보
,