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 글을 일어보면 되겠다.
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 |
---|
댓글