본문 바로가기
SPRING/Restful 웹서비스 설정

[Spring 3.0] Restful 웹 서비스 구현

by 정윤재 2011. 10. 19.

restful 웹서비스란

http://localhost:8080/push_web_server/reg/user/1234

이런식으로 요청 했을 때
URI 에서 user에 매치 되는 것이 1234 이므로
1234 를 reg 한다. 라는 방식으로 돌아간다.

여기까지는 rest 방식에 대한 설명이고 웹서비스가 들어갔다는 얘기는

4가지 HTTP 메소드(GET,POST,PUT,DELETE) 를 사용하여 단어에 맞는 작동을 body 내용을 참고하여 작동하도록 하는 것이다.
(GET-정보가져오기,POST-정보 추가 하기,PUT-정보 수정 하기,DELETE-정보삭제하기)
그리고 BODY 내용은 XML이 기본이다.(SOAP 웹서비스는 태그형식이 정해져 있지만
Restful 은 정해져 있지 않다.)

다른 프레임워크들은 모르겠으나 스프링 프레임 워크의 최신판에서는 쉽게
(3.0 이상) restful 방식을 구현하도록 작성할 수 있다.

바로 구현 방법 소스를 보는게 이해가 쉬울 것 같다.
(기본적으로 스프링 3.0 웹 mvc 가 정상 작동 하는 환경이라는 가정하에 진행한다.)

1. dispatcher-servlet 이 되는 xml 설정 파일에서

====================================================
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
 <!-- restful 방식 위해 이후 접근된 모든 접근 request 가 적용될 수 있도록 해야 확장자가 없는 url을 적용하여 적용 시킬 수 있다. /***/*** -->
 <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
   <property name="mediaTypes">
  <map>
     <entry key="xml" value="application/xml" />
     <!-- request header 에 application/xml 로 보내줘야함 -->
     <!-- key 가 URL 뒤에 .xml 방식으로 붙여줘야 함 -->
     <!--
http://localhost:8080/push_web_server/reg/user/1234.xml -->
     <!-- 실제로 1234.xml 파일은 없음 -->
     <entry key="json" value="application/json" />
  </map>
   </property>
 
   <property name="defaultViews">
  <list>
    <!-- JAXB XML View (rest 방식에서 마지막에 .xml 로 쓰면 결과가 넘어와서 View 화면에 XML 로 뿌려짐) -->
    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
   <constructor-arg>
    <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
       <property name="classesToBeBound">
     <list>
        <value>com.incross.dto.UserDTO</value>
        <!-- value>com.incross.dto.UserListDTO</value -->
     </list>
       </property>
    </bean>
   </constructor-arg>
    </bean>
        <!-- JSON View -->
    <bean
   class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
    </bean>
   </list>
   </property>
   <property name="ignoreAcceptHeader" value="true" />
 
 </bean>

<!-- 내부에서 POST 메소드의 body로 넘어오는 XML 값을 자동 파싱 하기 위함 -->
<bean id="jaxbMarshaller"
class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
 <list>
     <value>com.incross.dto.UserDTO</value>
 </list>
</property>
</bean>

====================================================
와 같이 <beans>태그 안에 설정한다.

2. Controller 에 restful 웹서비스 사용 메소드를 추가한다.

import java.io.StringReader;
import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.incross.dto.UserDTO;
import com.incross.user_register.service.User_Register_Service;

@Controller
@RequestMapping("/reg")
public class UserRegisterController {
   ..........................

   @Autowired
   public Jaxb2Marshaller jaxb2Mashaller;
   //dispatcher-servlet 에서 jaxb2Mashaller 설정함


 @RequestMapping(value = "/user/{user}", method = RequestMethod.PUT)
 public String getUser(@PathVariable String user, ModelMap model,HttpServletRequest request,@RequestBody String body) {
  logger.debug("***********enter controller restful test message send ***********");
  Source source = new StreamSource(new StringReader(body));
  UserDTO userDTO = (UserDTO) jaxb2Mashaller.unmarshal(source);
  //POST 로 XML 방식으로 넘어오는 값 parsing 함
  //보낼때 http 헤더에 Content-type:application/xml 로 만들어서 데이터 보내야함
  
  logger.debug("user::"+user);
  logger.debug("userDTO::"+userDTO.getUSER_ID()+"::"+userDTO.getPASSWORD());
// URL 과 body 데이터 받은 값들을 찍어서 확인함  

  userDTO.setUSER_ID("shonm");
  userDTO.setPASSWORD("koei4444");
  model.addAttribute("userDTO",userDTO);
  
  return "push_test/restful_result";
  //아무웹페이지나 상관 없음 (페이지가 있기만 하면 됨)
 }  
}

3. XML 로 Requeset 받거나 Response 보여줄 DTO 작성

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="user")
//xml 의 root 태그
public class UserDTO {
private String USER_ID;
private String PASSWORD;
public String getUSER_ID() {
 return USER_ID;
}
@XmlElement
//xml 일반 element 태그
public void setUSER_ID(String uSER_ID) {
 USER_ID = uSER_ID;
}
public String getPASSWORD() {
 return PASSWORD;
}
@XmlElement
public void setPASSWORD(String pASSWORD) {
 PASSWORD = pASSWORD;
}
}


4. forwarding 될 jsp 페이지 작성
(페이지만 있고 아무것도 없어도 됨-restful_result.jsp)

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!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>Insert title here</title>
</head>
<body>
</body>
</html>
========================================================

확인 방법
리눅스 콘솔창에서

curl -X POST -HContent-type:application/xml --data "<?xml version='1.0' encoding='UTF-8'?><user><USER_ID>3</USER_ID><PASSWORD>guest3</PASSWORD></user>"
http://124.136.171.168:8080/push_web_server/reg/user/1234.xml

이런 식으로 테스트 해보면 됨
http header 의 Content-type:application/xml  이렇게 설정해 주고
내부 request 데이터는
"<user><USER_ID>3</USER_ID><PASSWORD>guest3</PASSWORD></user>"
와 같이 XML 로 작성해 줌
그리고 위와 같이 작성할 경우 URI 맨 마지막에 .xml 을 붙여주어 xml 방식 view
방식이라는 것을 표현해 주어야함
dispatcher-servlet 에
<entry key="xml" value="application/xml" /> 의
key="xml" 부분이 그걸 표현해 주는 것임 (xmll 이라고 하면 .xmll 이라고 붙여주면됨)


위의 명령의 결과는

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user><PASSWORD>koei4444</PASSWORD><USER_ID>shonm</USER_ID></user>

와 같이 나옴

===============================================================
이 방식의 단점은 header 에 xml 방식을 표현해 줌에도 불구하고 .xml 이라는
헤더가 붙는다라는 점과 restful_result.jsp 파일을 쓸데 없이 만든다는 점이다.
이런 점에 대한 해결책은 다음 글에서 풀어보도록 하겠다
이 comment 를 붙일때 이미 난 2편을 다 써서 올렸다.
바로 [Spring 3.0] Restful 웹 서비스 구현 2 글을 일어보면 되겠다.

'SPRING > Restful 웹서비스 설정' 카테고리의 다른 글

[Spring 3.0] Restful 웹 서비스 구현 2  (1) 2011.10.21

댓글