SlideShare une entreprise Scribd logo
1  sur  44
Spring 3 MVC Rest  (3.0.5 기준) 김용환 Knight76 at gmail.com Knight76.tistory.com 맛보기
특징 REST를 쓰기 위해서 Spring MVC 모델을 그대로 차용, Annotation 이용(Controller) JSR 311을 따르지는 않지만, 대부분의 기능 구현 하나의 리소스는 여러 개의 Represenation을 가질 수있도록함 (JSON/XML/ATOM/RSS) 브라우저에서 지원하지 않는 PUT & POST 요청을 처리할 수 있음 Custom parser 이용 가능 UTIL(converter..) 클래스 지원 => REST 관련 Conception만 조금 공부하면 되고, 나머지는 기존 MVC만 알면 되기 까닭에재사용성이 큼
Spring 3 Rest 지원#1 Annotation 지원  @Controller : MVC @RequestMapping : HTTP 메소드, URI, 헤더 처리@RequestMapping(method=RequestMethod.GET, value="/members",  @PathVariable: 메소드 안에서 파라미터와매핑하기 위해서 사용public ModelAndViewgetEmployee(@PathVariable String id) { … }  @RequestParam : URL 매개변수 이용 @RequestHeader @RequestBody @HttpEntity<T> @ResponseEntity<T> : 정의한대로 response 리턴 public @ResponseBody Employee getEmployeeBy(@RequestParam("name") String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…}  public ResponseEntity<String> method(HttpEntity<String> entity) {…}
Spring 3 Rest 지원 #1 Annotation 지원 @ResponseStatus @ExceptionHandler
Spring 3 Rest 지원 #2 ContentNegotiatingViewResolver 요청 데이터 포맷에 맞춰 다양한 MIME(미디어 타입) 이나 content type으로 전달 가능 ATOM, RSS, XML, JSON, OXM 예) http://localhost:8080/fruit/banana.xml http://localhost:8080/fruit/banana.rss http://localhost:8080/fruit/banana.html Accept : application/xml Accept : application/json Accept : application/html
좋은자료 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html http://dev.anyframejava.org/docs/anyframe/plugin/restweb/1.0.1/reference/html/index.html http://www.mkyong.com/spring-mvc/spring-3-mvc-contentnegotiatingviewresolver-example/ http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
개념 살펴보기
@Controller @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) 	public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); 		return "list"; 	} … }
Request Parameter Type Strong @Controller @RequestMapping("/restful") public class RestfulController { 	@RequestMapping(value = "/message/{name}", method = RequestMethod.GET) 	public String getMessage(@PathVariableString name, ModelMap model) { model.addAttribute("message", name); 		return "list"; 	} … }
@PathVariable @Controller @RequestMapping("/restful") public class RestfulController { 	@RequestMapping(value = "/message/{name}", method = RequestMethod.GET) 	public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); 		return "list"; 	} … }
@ResponseBody @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/messagebody/{message}", method = RequestMethod.GET) @ResponseBody public Body getMessageBody(@PathVariable String message, ModelMap model) { Body body = new Body(); body.setMessage(message); return body; } … } @XmlRootElement(name = "body") public class Body { @XmlElement private String msg; public String getMessage() {    return msg; } public void setMessage(String message) {     this.msg = message; } }
@ResponseStatus @RequestMapping(value = "/exception", method = RequestMethod.GET) public String throwException() {     throw new ResourceNotFoundException(); } @ExceptionHandler(ResourceNotFoundException.class) @ResponseStatus(value = HttpStatus.BAD_GATEWAY)  public void handleNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) { System.out.println("handleNotFoundException:" + ex); } ….. class ResourceNotFoundException extends RuntimeException {  }  $ curl -i  localhost:8080/restful/exception HTTP/1.1 502 Bad Gateway Content-Length: 0 Server: Jetty(6.1.26) 결과
Rest 방식과 기존 파라미터요청 방식 을 같이 사용가능?? @RequestMapping(value = "/test/{name}/id/{id}", method = RequestMethod.GET) public String getString(@PathVariable String name, @PathVariableint id,                                 String email, ModelMap model) { model.addAttribute("message", name); model.addAttribute("id", id); model.addAttribute("email", email);     return "test"; } 가능 // test.jsp <html> <head></head> <body> <h1>Test</h1> <h3>message : ${message}</h3> <h3>email : ${email}</h3> </body> </html> $ curl http://localhost:8080/restful/test/jaja/id/11?email=aaa@google.com <html> <head></head> <body>         <h1>Test</h1>         <h3>message : jaja</h3>         <h3>email : aaa@google.com</h3> </body> </html> 결과
JSON Payload 요청 #1 @Controller @RequestMapping("/comm") @ResponseStatus(value = HttpStatus.ACCEPTED) public class JsonRequestController {     @RequestMapping(method = RequestMethod.GET)      @ResponseStatus(value=HttpStatus.FOUND)     public void sendFruitMessage(@RequestBody Message name) { System.out.println("name : " + name.getName());         return ;     } } Spring MVC가  알아서 deserialization을 해줌 @XmlRootElement(name = "message") public class Message { @XmlElement private String name; public String getName() { return name; }       public void setName(String name) { 	this.name = name;      } }
JSON Payload 요청 #2 결과 : xml  <클라이언트> $ curl -i -H "Content-Type: application/xml" -X get -d '<message><name>Kim Yong Hwan</name></message>' localhost:8080/comm HTTP/1.1 302 Found Content-Length: 0 Server: Jetty(6.1.26) <서버> name : Kim Yong Hwan 결과 : json <클라이언트> $ curl  -i -H "Content-Type: application/json" -X get -d '{"name":"Kim Yong Hwan"}' localhost:8080/comm HTTP/1.1 302 Found Content-Length: 0 Server: Jetty(6.1.26) <서버> name : Kim Yong Hwan
DEMO
WEB.XML <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring Web MVC Rest Demo Application</display-name> <servlet>     <servlet-name>mvc-dispatcher</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>     <servlet-name>mvc-dispatcher</servlet-name>     <url-pattern>/</url-pattern> </servlet-mapping> <context-param>     <param-name>contextConfigLocation</param-name>     <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </context-param> <listener>     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
mvc-dispatcher-servlet.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd         http://www.springframework.org/schema/context          http://www.springframework.org/schema/context/spring-context-3.0.xsd         http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.google.controller" /> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">     <property name="prefix" value="/WEB-INF/pages/" />     <property name="suffix" value=".jsp" /> </bean> </beans>
RestfulController.java @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) 	public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); 		return "list"; 	} @RequestMapping(value = "/command/{id}/content/{content}", method = RequestMethod.GET) 	public String getCommand(@PathVariable("id") String id, @PathVariable("content") long content, ModelMap model) { model.addAttribute("id", id); model.addAttribute("content", content); 		return "command"; 	} @RequestMapping(value = "/link/{id}", method = RequestMethod.DELETE) 	public String deleteLink(@PathVariable("id") String id, ModelMap model) { model.addAttribute("id", id); 		return "delete"; 	} }
JSP 소스 // WEB-INF/pages/list.jsp <html> <body> <h1>Spring MVC Restful Test</h1> <h3>message : ${message}</h3> </body> </html> // WEB-INF/pages/command.jsp <html> <body> <h1>Spring MVC Restful Test</h1>     <h3>command id : ${id}</h3> <h3>content : ${content}</h3> </body> </html> // WEB-INF/pages/delete.jsp <html> <body> <h1>Spring MVC Restful Test</h1> <h3>deleted id : ${id}</h3> </body> </html>
결과 (웹 브라우저) http://localhost:8080/restful/message/reset http://localhost:8080/restful/command/aa/content/111
결과 (리눅스/Cygwin) curl -X DELETE http://localhost:8080/restful/link/1  curl -X DELETE http://localhost:8080/restful/message/3
Content Negotiation
Content Negotiation HTTP 1.1 스펙에서 정의 의미 media type, 언어, 문자집합, 인코딩 등에 대해 브라우저가 제공한 선호도에 따라 자원의 가장 적합한 표현을 선택.  불완전한 협상 정보를 보내는 브라우저의 요청을 지능적으로 처리하는 기능 일반적으로 다른 프로토콜을 쓰려면, request의 “type” 파라미터를 확인하고, 이에 맞는 marshalling정보를 전달해야 한다. 트위터API가 이렇게 사용되고 있음 Spring MVC에서는 한번에 해결해주는 클래스 사용 ContentNegotiatingViewResolver
DEMO
FruitController @Controller @RequestMapping("/fruit") public class FruitController{     @RequestMapping(value="{fruitName}", method = RequestMethod.GET)     public String getFruit(@PathVariable String fruitName, ModelMap model) {     Fruit fruit = new Fruit(fruitName, 1000); model.addAttribute("model", fruit);     return "listfruit";     } }
Fruit @XmlRootElement(name = "fruit") public class Fruit { String name; intquality; public Fruit() {} public Fruit(String name, int quality) {     this.name = name; this.quality = quality; } @XmlElement public void setName(String name) { this.name = name; } @XmlElement public void setQuality(int quality) { this.quality = quality; } }
mvc-dispatcher-servlet.xml <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">   <property name="order" value="1" />   <property name="mediaTypes"> <map>    <entry key="json" value="application/json" />    <entry key="xml" value="application/xml" />    <entry key="rss" value="application/rss+xml" /> </map>   </property>   <property name="defaultViews"> <list>   <!-- JSON View -->   <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">   </bean>   <!-- RSS View -->   <bean class="com.google.rss.RssFeedView" />   <!-- JAXB XML View -->   <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <constructor-arg> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">    <property name="classesToBeBound"> <list>    <value>com.google.bean.Fruit</value> </list>    </property> </bean> </constructor-arg>   </bean>  </list>   </property>   <property name="ignoreAcceptHeader" value="true" /> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="order" value="2" /> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean>
결과 $ curl -H 'Accept: application/xml' localhost:8080/fruit/banana.xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?><fruit><name>banana</name ><quality>1000</quality></fruit> $ curl -H 'Accept: application/rss'localhost:8080/fruit/banana.rss <?xml version="1.0" encoding="UTF-8"?> <rssxmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">   <channel>     <title>Sample Title</title>     <link>http://google.com</link>     <description>Sample Description</description>     <item>       <link>http://www.google.com</link>       <content:encoded>banana1000</content:encoded>       <author>Test</author>     </item>   </channel> </rss> $ curl -H 'Accept: application/json' localhost:8080/fruit/banana.json {"model":{"quality":1000,"name":"banana"}}
Demo에서 @XmlElement사용시 유의할 점 Set메소드를 사용하려면, 다음과 같이 한다.   클래스의 멤버 필드에서 @XmlElement를 정의할 때는 set 메소드를 사용하지 않는다.  @XmlRootElement(name = "fruit") public class Fruit {     private String name;     private int quality; @XmlElement         public void setBody(Body body) { this.body= body;     }     public String getName() {         return name;     } @XmlElement     public void setQuality(int quality) { this.quality= quality;     }     public intgetQuality() {        return quality;     } … } @XmlRootElement(name = "fruit") public class Fruit { @XmlElement     private String name; @XmlElement     private int quality;     public String getName() {         return name;     }     public intgetQuality() {        return quality;     } … } JAXB에서 property를 읽을 때, 잘 사용해야 하는 구조
Demo에서 @XmlElement사용시유의할 점 Body 클래스앞에@XmlRootElement선언이 되어 있으면, Fruit 클래스 에서 @XmlElement를 사용하지 않아도 된다. @XmlRootElement(name = "body") public class Body {     @XmlElement     private String msg;      // set/get accessory …. } @XmlRootElement(name = "fruit") public class Fruit { @XmlElement     private String name; @XmlElement     private int quality;     private Body body;     public String getName() {         return name;     }     public intgetQuality() {        return quality;     } … }
웹 브라우져에서의PUT/DELETE의 제약
웹 브라우져 제약 #1 GET/POST만 쓸 수 있는 웹 브라우져가 있을 수 있다. PUT과 DELETE 을 쓰기 위해서는 trick을 써야 한다. HiddenHttpMethodFilter이용 Web.xml   <filter>        <filter-name>httpMethodFilter</filter-name>        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>    </filter>        <filter-mapping>        <filter-name>httpMethodFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>
웹 브라우져 제약 #2 // spring mvc form tag <form:form method="delete">  <p class="submit"><input type="submit" value="Delete Pet"/></p>  </form:form> @RequestMapping(method = RequestMethod.DELETE) public String deletePet(@PathVariableintownerId, @PathVariableintpetId) { this.clinic.deletePet(petId);     return "redirect:/owners/" + ownerId; } 아마도 예전처럼 내부적으로 name=“_method” value=“Delete” 하는 형태로  전달하고, Spring 서버는 이 정보를 바탕으로 구현 했을 것으로 예상 <form action="POST">   <input type="hidden" id="_method" value="PUT"> </form>
PUT/DELETE in HTML HTML version 4 과 XHTML 1에서는 HTML  form안의 HTTP 요청은 GET과 POST 방식만 허용. 그동안put/delete 메소드를 사용하려면, XMLHttpRequest를 이용하였음 HTTP상에서는 ok! HTML5에서 put/delete는 사용하지 못한다고 나와 있음 http://www.w3.org/TR/html5-diff/ Using PUT and DELETE as HTTP methods for the form element is no longer supported. 참고
클라이언트 API : RestTemplate
클라이언트 API Apache Commons의 HttpClient대신 쉽게 사용할 수 있는 RestTemplate구성 <bean id="restTemplate"  class="org.springframework.web.client.RestTemplate"> <property name="messageConverters"> 	<list> 	<ref bean="marshallingConverter" /> 	<ref bean="atomConverter"  /> 	<ref bean="jsonConverter" /> 	</list> </property> </bean>
클라이언트 API XML 요청 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_XML); HttpEntity<String> entity = new HttpEntity<String>(headers); ResponseEntity<EmployeeList> response = restTemplate.exchange( "http://localhost:8080/rest/service/emps",  HttpMethod.GET, entity, EmployeeList.class); EmployeeListingemployees = response.getBody(); // handle the employees
클라이언트 API 새직원포스팅/ 삭제 Employee newEmp = new Employee(11, “tguest", “tguest@google.com"); HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp); restTemplate.put( 	"http://localhost:8080/rest/service/emp/{id}", entity, "99"); restTemplate.delete( 	"http://localhost:8080/rest/service/emp/{id}", "99");
RestTemplate클래스 클라이언트에서 사용할 수 있는 Rest API
RestTemplate클래스
RestTemplate예제 Map<String, String> vars = new HashMap<String, String>(); vars.put("id", "111"); vars.put("content", "222"); RestTemplaterestTemplate = new RestTemplate(); String result = restTemplate.getForObject("http://localhost:8080/restful/command/{id}/content/{content}", String.class, vars); System.out.println("result : " + result); result : <html> <body> <h1>Spring MVC Restful Test</h1>     <h3>command id : 111</h3> <h3>content : 222</h3> </body> </html> 결과
ExampleCode Knight76.tistory.com에서 ‘spring mvc restful’ 검색
End of Document

Contenu connexe

Tendances

WSO2Con USA 2015: Securing your APIs: Patterns and More
WSO2Con USA 2015: Securing your APIs: Patterns and MoreWSO2Con USA 2015: Securing your APIs: Patterns and More
WSO2Con USA 2015: Securing your APIs: Patterns and MoreWSO2
 
Creating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationCreating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationMicha Kops
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Zend by Rogue Wave Software
 
Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction ISSGC Summer School
 
Unify Earth Observation products access with OpenSearch
Unify Earth Observation products access with OpenSearchUnify Earth Observation products access with OpenSearch
Unify Earth Observation products access with OpenSearchGasperi Jerome
 
Your rest api using laravel
Your rest api using laravelYour rest api using laravel
Your rest api using laravelSulaeman .
 
Iss letcure 7_8
Iss letcure 7_8Iss letcure 7_8
Iss letcure 7_8Ali Habeeb
 
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREY
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREYBUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREY
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREYCodeCore
 
Pulsar Architectural Patterns for CI/CD Automation and Self-Service
Pulsar Architectural Patterns for CI/CD Automation and Self-ServicePulsar Architectural Patterns for CI/CD Automation and Self-Service
Pulsar Architectural Patterns for CI/CD Automation and Self-ServiceDevin Bost
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsSolution4Future
 
Flask restfulservices
Flask restfulservicesFlask restfulservices
Flask restfulservicesMarcos Lin
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLitecharsbar
 
An Introduction to Solr
An Introduction to SolrAn Introduction to Solr
An Introduction to Solrtomhill
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long jaxconf
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in rubyHiroshi Nakamura
 

Tendances (20)

httpie
httpiehttpie
httpie
 
Advancedservletsjsp
AdvancedservletsjspAdvancedservletsjsp
Advancedservletsjsp
 
WSO2Con USA 2015: Securing your APIs: Patterns and More
WSO2Con USA 2015: Securing your APIs: Patterns and MoreWSO2Con USA 2015: Securing your APIs: Patterns and More
WSO2Con USA 2015: Securing your APIs: Patterns and More
 
Creating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationCreating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat Application
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
 
Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction Session 40 : SAGA Overview and Introduction
Session 40 : SAGA Overview and Introduction
 
Unify Earth Observation products access with OpenSearch
Unify Earth Observation products access with OpenSearchUnify Earth Observation products access with OpenSearch
Unify Earth Observation products access with OpenSearch
 
Your rest api using laravel
Your rest api using laravelYour rest api using laravel
Your rest api using laravel
 
Iss letcure 7_8
Iss letcure 7_8Iss letcure 7_8
Iss letcure 7_8
 
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREY
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREYBUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREY
BUILDING MODERN PYTHON WEB FRAMEWORKS USING FLASK WITH NEIL GREY
 
Pulsar Architectural Patterns for CI/CD Automation and Self-Service
Pulsar Architectural Patterns for CI/CD Automation and Self-ServicePulsar Architectural Patterns for CI/CD Automation and Self-Service
Pulsar Architectural Patterns for CI/CD Automation and Self-Service
 
Rest api with Python
Rest api with PythonRest api with Python
Rest api with Python
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutions
 
Flask restfulservices
Flask restfulservicesFlask restfulservices
Flask restfulservices
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
 
An Introduction to Solr
An Introduction to SolrAn Introduction to Solr
An Introduction to Solr
 
Rest in flask
Rest in flaskRest in flask
Rest in flask
 
Learning Dtrace
Learning DtraceLearning Dtrace
Learning Dtrace
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in ruby
 

En vedette

ITU Letter to the President of Indonesia (IM2 Case)
ITU Letter to the President of Indonesia (IM2 Case)ITU Letter to the President of Indonesia (IM2 Case)
ITU Letter to the President of Indonesia (IM2 Case)ICT Watch
 
Poly Clip Zertificate
Poly Clip ZertificatePoly Clip Zertificate
Poly Clip ZertificateRamon Ortega
 
Ejecucion presupuesto 2012_2014
Ejecucion presupuesto 2012_2014Ejecucion presupuesto 2012_2014
Ejecucion presupuesto 2012_2014Vrac Unfv
 
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, Sayla
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, SaylaJanhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, Sayla
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, SaylaRaj Saubhag
 
Elastische Skalierbarkeit für Web-Anwendungen
Elastische Skalierbarkeit für Web-AnwendungenElastische Skalierbarkeit für Web-Anwendungen
Elastische Skalierbarkeit für Web-AnwendungenAxel Irriger
 
Zanox se instala en España. Sep2003. Revista Estrategias.
Zanox se instala en España. Sep2003. Revista Estrategias. Zanox se instala en España. Sep2003. Revista Estrategias.
Zanox se instala en España. Sep2003. Revista Estrategias. Retelur Marketing
 
Consigli & Ricette per piccoli gourmet
Consigli & Ricette per piccoli gourmetConsigli & Ricette per piccoli gourmet
Consigli & Ricette per piccoli gourmetPiero Conte
 
Portafolio de Cultura Neuroactiva
Portafolio de Cultura NeuroactivaPortafolio de Cultura Neuroactiva
Portafolio de Cultura NeuroactivaCultura Neuroactiva
 
brochure ck line
brochure ck linebrochure ck line
brochure ck lineDinda Artya
 
Omam Consultants Presentation
Omam Consultants   PresentationOmam Consultants   Presentation
Omam Consultants Presentationaopu64
 
Bits arte y formas geométricas
Bits arte y formas geométricasBits arte y formas geométricas
Bits arte y formas geométricasMiriam Sedes López
 
Factor 10. Recursos Físicos y Financieros
Factor 10. Recursos Físicos y FinancierosFactor 10. Recursos Físicos y Financieros
Factor 10. Recursos Físicos y Financierossisauq
 

En vedette (20)

ITU Letter to the President of Indonesia (IM2 Case)
ITU Letter to the President of Indonesia (IM2 Case)ITU Letter to the President of Indonesia (IM2 Case)
ITU Letter to the President of Indonesia (IM2 Case)
 
Poly Clip Zertificate
Poly Clip ZertificatePoly Clip Zertificate
Poly Clip Zertificate
 
Ejecucion presupuesto 2012_2014
Ejecucion presupuesto 2012_2014Ejecucion presupuesto 2012_2014
Ejecucion presupuesto 2012_2014
 
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, Sayla
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, SaylaJanhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, Sayla
Janhit Humanitarian Magazine 2013 - Raj Saubhag Ashram, Sayla
 
Aplicando lo aprendido con las tic
Aplicando lo aprendido con las ticAplicando lo aprendido con las tic
Aplicando lo aprendido con las tic
 
Cl130
Cl130Cl130
Cl130
 
PAFonteyne_ExtendedCV_2015
PAFonteyne_ExtendedCV_2015PAFonteyne_ExtendedCV_2015
PAFonteyne_ExtendedCV_2015
 
Elastische Skalierbarkeit für Web-Anwendungen
Elastische Skalierbarkeit für Web-AnwendungenElastische Skalierbarkeit für Web-Anwendungen
Elastische Skalierbarkeit für Web-Anwendungen
 
Info mipa p85 lang
Info mipa p85 langInfo mipa p85 lang
Info mipa p85 lang
 
Zanox se instala en España. Sep2003. Revista Estrategias.
Zanox se instala en España. Sep2003. Revista Estrategias. Zanox se instala en España. Sep2003. Revista Estrategias.
Zanox se instala en España. Sep2003. Revista Estrategias.
 
Consigli & Ricette per piccoli gourmet
Consigli & Ricette per piccoli gourmetConsigli & Ricette per piccoli gourmet
Consigli & Ricette per piccoli gourmet
 
Portafolio de Cultura Neuroactiva
Portafolio de Cultura NeuroactivaPortafolio de Cultura Neuroactiva
Portafolio de Cultura Neuroactiva
 
brochure ck line
brochure ck linebrochure ck line
brochure ck line
 
Omam Consultants Presentation
Omam Consultants   PresentationOmam Consultants   Presentation
Omam Consultants Presentation
 
Manejo del embarazo no deseado (1)
Manejo del embarazo no deseado (1)Manejo del embarazo no deseado (1)
Manejo del embarazo no deseado (1)
 
Musica
MusicaMusica
Musica
 
Bits arte y formas geométricas
Bits arte y formas geométricasBits arte y formas geométricas
Bits arte y formas geométricas
 
GKA deel 1 college 9
GKA deel 1 college 9GKA deel 1 college 9
GKA deel 1 college 9
 
Calendario de Actividades en Acapulco
Calendario de Actividades en AcapulcoCalendario de Actividades en Acapulco
Calendario de Actividades en Acapulco
 
Factor 10. Recursos Físicos y Financieros
Factor 10. Recursos Físicos y FinancierosFactor 10. Recursos Físicos y Financieros
Factor 10. Recursos Físicos y Financieros
 

Similaire à Spring MVC 3 Restful

SCWCD 2. servlet req - resp (cap3 - cap4)
SCWCD 2. servlet   req - resp (cap3 - cap4)SCWCD 2. servlet   req - resp (cap3 - cap4)
SCWCD 2. servlet req - resp (cap3 - cap4)Francesco Ierna
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHPKing Foo
 
There is time for rest
There is time for rest There is time for rest
There is time for rest SoftServe
 
Jsp/Servlet
Jsp/ServletJsp/Servlet
Jsp/ServletSunil OS
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Server-side Technologies in Java
Server-side Technologies in JavaServer-side Technologies in Java
Server-side Technologies in JavaAnirban Majumdar
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
Session12 J2ME Generic Connection Framework
Session12 J2ME Generic Connection FrameworkSession12 J2ME Generic Connection Framework
Session12 J2ME Generic Connection Frameworkmuthusvm
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座Li Yi
 
Request dispatching in servlet
Request dispatching in servletRequest dispatching in servlet
Request dispatching in servletvikram singh
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Rapid API development examples for Impress Application Server / Node.js (jsfw...
Rapid API development examples for Impress Application Server / Node.js (jsfw...Rapid API development examples for Impress Application Server / Node.js (jsfw...
Rapid API development examples for Impress Application Server / Node.js (jsfw...Timur Shemsedinov
 
Introduction To ASP.NET MVC
Introduction To ASP.NET MVCIntroduction To ASP.NET MVC
Introduction To ASP.NET MVCAlan Dean
 
RestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSRestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSNeil Ghosh
 
Bt0083 server side programing 2
Bt0083 server side programing  2Bt0083 server side programing  2
Bt0083 server side programing 2Techglyphs
 

Similaire à Spring MVC 3 Restful (20)

SCWCD 2. servlet req - resp (cap3 - cap4)
SCWCD 2. servlet   req - resp (cap3 - cap4)SCWCD 2. servlet   req - resp (cap3 - cap4)
SCWCD 2. servlet req - resp (cap3 - cap4)
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
 
There is time for rest
There is time for rest There is time for rest
There is time for rest
 
Jsp/Servlet
Jsp/ServletJsp/Servlet
Jsp/Servlet
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Server-side Technologies in Java
Server-side Technologies in JavaServer-side Technologies in Java
Server-side Technologies in Java
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Session12 J2ME Generic Connection Framework
Session12 J2ME Generic Connection FrameworkSession12 J2ME Generic Connection Framework
Session12 J2ME Generic Connection Framework
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座
 
Request dispatching in servlet
Request dispatching in servletRequest dispatching in servlet
Request dispatching in servlet
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Rapid API development examples for Impress Application Server / Node.js (jsfw...
Rapid API development examples for Impress Application Server / Node.js (jsfw...Rapid API development examples for Impress Application Server / Node.js (jsfw...
Rapid API development examples for Impress Application Server / Node.js (jsfw...
 
Introduction To ASP.NET MVC
Introduction To ASP.NET MVCIntroduction To ASP.NET MVC
Introduction To ASP.NET MVC
 
RestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSRestFull Webservices with JAX-RS
RestFull Webservices with JAX-RS
 
Bt0083 server side programing 2
Bt0083 server side programing  2Bt0083 server side programing  2
Bt0083 server side programing 2
 
Servlet
Servlet Servlet
Servlet
 
Android and REST
Android and RESTAndroid and REST
Android and REST
 

Plus de knight1128

Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)knight1128
 
Google Protocol buffer
Google Protocol bufferGoogle Protocol buffer
Google Protocol bufferknight1128
 
Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicknight1128
 
Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능knight1128
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
공유 Jdk 7-2-project coin
공유 Jdk 7-2-project coin공유 Jdk 7-2-project coin
공유 Jdk 7-2-project coinknight1128
 
공유 Jdk 7-1-short introduction
공유 Jdk 7-1-short introduction공유 Jdk 7-1-short introduction
공유 Jdk 7-1-short introductionknight1128
 
아마존 Aws 서비스_연구
아마존 Aws 서비스_연구아마존 Aws 서비스_연구
아마존 Aws 서비스_연구knight1128
 
구글크롬Os
구글크롬Os구글크롬Os
구글크롬Osknight1128
 
하이브리드앱
하이브리드앱하이브리드앱
하이브리드앱knight1128
 
오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유knight1128
 
Ssl 하드웨어 가속기를 이용한 성능 향상
Ssl 하드웨어 가속기를 이용한 성능 향상Ssl 하드웨어 가속기를 이용한 성능 향상
Ssl 하드웨어 가속기를 이용한 성능 향상knight1128
 

Plus de knight1128 (18)

Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
Hancom MDS Conference - KAKAO DEVOPS Practice (카카오 스토리의 Devops 사례)
 
Comet
CometComet
Comet
 
Apache avro
Apache avroApache avro
Apache avro
 
Apache Thrift
Apache ThriftApache Thrift
Apache Thrift
 
Redis
RedisRedis
Redis
 
Google Protocol buffer
Google Protocol bufferGoogle Protocol buffer
Google Protocol buffer
 
Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamic
 
Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능Jdk(java) 7 - 6 기타기능
Jdk(java) 7 - 6 기타기능
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Jdk 7 3-nio2
Jdk 7 3-nio2Jdk 7 3-nio2
Jdk 7 3-nio2
 
공유 Jdk 7-2-project coin
공유 Jdk 7-2-project coin공유 Jdk 7-2-project coin
공유 Jdk 7-2-project coin
 
공유 Jdk 7-1-short introduction
공유 Jdk 7-1-short introduction공유 Jdk 7-1-short introduction
공유 Jdk 7-1-short introduction
 
아마존 Aws 서비스_연구
아마존 Aws 서비스_연구아마존 Aws 서비스_연구
아마존 Aws 서비스_연구
 
속도체크
속도체크속도체크
속도체크
 
구글크롬Os
구글크롬Os구글크롬Os
구글크롬Os
 
하이브리드앱
하이브리드앱하이브리드앱
하이브리드앱
 
오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유오픈소스를 활용한 Batch_처리_플랫폼_공유
오픈소스를 활용한 Batch_처리_플랫폼_공유
 
Ssl 하드웨어 가속기를 이용한 성능 향상
Ssl 하드웨어 가속기를 이용한 성능 향상Ssl 하드웨어 가속기를 이용한 성능 향상
Ssl 하드웨어 가속기를 이용한 성능 향상
 

Dernier

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 

Dernier (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Spring MVC 3 Restful

  • 1. Spring 3 MVC Rest (3.0.5 기준) 김용환 Knight76 at gmail.com Knight76.tistory.com 맛보기
  • 2. 특징 REST를 쓰기 위해서 Spring MVC 모델을 그대로 차용, Annotation 이용(Controller) JSR 311을 따르지는 않지만, 대부분의 기능 구현 하나의 리소스는 여러 개의 Represenation을 가질 수있도록함 (JSON/XML/ATOM/RSS) 브라우저에서 지원하지 않는 PUT & POST 요청을 처리할 수 있음 Custom parser 이용 가능 UTIL(converter..) 클래스 지원 => REST 관련 Conception만 조금 공부하면 되고, 나머지는 기존 MVC만 알면 되기 까닭에재사용성이 큼
  • 3. Spring 3 Rest 지원#1 Annotation 지원 @Controller : MVC @RequestMapping : HTTP 메소드, URI, 헤더 처리@RequestMapping(method=RequestMethod.GET, value="/members", @PathVariable: 메소드 안에서 파라미터와매핑하기 위해서 사용public ModelAndViewgetEmployee(@PathVariable String id) { … } @RequestParam : URL 매개변수 이용 @RequestHeader @RequestBody @HttpEntity<T> @ResponseEntity<T> : 정의한대로 response 리턴 public @ResponseBody Employee getEmployeeBy(@RequestParam("name") String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…} public ResponseEntity<String> method(HttpEntity<String> entity) {…}
  • 4. Spring 3 Rest 지원 #1 Annotation 지원 @ResponseStatus @ExceptionHandler
  • 5. Spring 3 Rest 지원 #2 ContentNegotiatingViewResolver 요청 데이터 포맷에 맞춰 다양한 MIME(미디어 타입) 이나 content type으로 전달 가능 ATOM, RSS, XML, JSON, OXM 예) http://localhost:8080/fruit/banana.xml http://localhost:8080/fruit/banana.rss http://localhost:8080/fruit/banana.html Accept : application/xml Accept : application/json Accept : application/html
  • 6. 좋은자료 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html http://dev.anyframejava.org/docs/anyframe/plugin/restweb/1.0.1/reference/html/index.html http://www.mkyong.com/spring-mvc/spring-3-mvc-contentnegotiatingviewresolver-example/ http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
  • 8. @Controller @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); return "list"; } … }
  • 9. Request Parameter Type Strong @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) public String getMessage(@PathVariableString name, ModelMap model) { model.addAttribute("message", name); return "list"; } … }
  • 10. @PathVariable @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); return "list"; } … }
  • 11. @ResponseBody @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/messagebody/{message}", method = RequestMethod.GET) @ResponseBody public Body getMessageBody(@PathVariable String message, ModelMap model) { Body body = new Body(); body.setMessage(message); return body; } … } @XmlRootElement(name = "body") public class Body { @XmlElement private String msg; public String getMessage() { return msg; } public void setMessage(String message) { this.msg = message; } }
  • 12. @ResponseStatus @RequestMapping(value = "/exception", method = RequestMethod.GET) public String throwException() { throw new ResourceNotFoundException(); } @ExceptionHandler(ResourceNotFoundException.class) @ResponseStatus(value = HttpStatus.BAD_GATEWAY) public void handleNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) { System.out.println("handleNotFoundException:" + ex); } ….. class ResourceNotFoundException extends RuntimeException { } $ curl -i localhost:8080/restful/exception HTTP/1.1 502 Bad Gateway Content-Length: 0 Server: Jetty(6.1.26) 결과
  • 13. Rest 방식과 기존 파라미터요청 방식 을 같이 사용가능?? @RequestMapping(value = "/test/{name}/id/{id}", method = RequestMethod.GET) public String getString(@PathVariable String name, @PathVariableint id, String email, ModelMap model) { model.addAttribute("message", name); model.addAttribute("id", id); model.addAttribute("email", email); return "test"; } 가능 // test.jsp <html> <head></head> <body> <h1>Test</h1> <h3>message : ${message}</h3> <h3>email : ${email}</h3> </body> </html> $ curl http://localhost:8080/restful/test/jaja/id/11?email=aaa@google.com <html> <head></head> <body> <h1>Test</h1> <h3>message : jaja</h3> <h3>email : aaa@google.com</h3> </body> </html> 결과
  • 14. JSON Payload 요청 #1 @Controller @RequestMapping("/comm") @ResponseStatus(value = HttpStatus.ACCEPTED) public class JsonRequestController { @RequestMapping(method = RequestMethod.GET) @ResponseStatus(value=HttpStatus.FOUND) public void sendFruitMessage(@RequestBody Message name) { System.out.println("name : " + name.getName()); return ; } } Spring MVC가 알아서 deserialization을 해줌 @XmlRootElement(name = "message") public class Message { @XmlElement private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
  • 15. JSON Payload 요청 #2 결과 : xml <클라이언트> $ curl -i -H "Content-Type: application/xml" -X get -d '<message><name>Kim Yong Hwan</name></message>' localhost:8080/comm HTTP/1.1 302 Found Content-Length: 0 Server: Jetty(6.1.26) <서버> name : Kim Yong Hwan 결과 : json <클라이언트> $ curl -i -H "Content-Type: application/json" -X get -d '{"name":"Kim Yong Hwan"}' localhost:8080/comm HTTP/1.1 302 Found Content-Length: 0 Server: Jetty(6.1.26) <서버> name : Kim Yong Hwan
  • 16. DEMO
  • 17. WEB.XML <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring Web MVC Rest Demo Application</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
  • 18. mvc-dispatcher-servlet.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" 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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.google.controller" /> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
  • 19. RestfulController.java @Controller @RequestMapping("/restful") public class RestfulController { @RequestMapping(value = "/message/{name}", method = RequestMethod.GET) public String getMessage(@PathVariable String name, ModelMap model) { model.addAttribute("message", name); return "list"; } @RequestMapping(value = "/command/{id}/content/{content}", method = RequestMethod.GET) public String getCommand(@PathVariable("id") String id, @PathVariable("content") long content, ModelMap model) { model.addAttribute("id", id); model.addAttribute("content", content); return "command"; } @RequestMapping(value = "/link/{id}", method = RequestMethod.DELETE) public String deleteLink(@PathVariable("id") String id, ModelMap model) { model.addAttribute("id", id); return "delete"; } }
  • 20. JSP 소스 // WEB-INF/pages/list.jsp <html> <body> <h1>Spring MVC Restful Test</h1> <h3>message : ${message}</h3> </body> </html> // WEB-INF/pages/command.jsp <html> <body> <h1>Spring MVC Restful Test</h1> <h3>command id : ${id}</h3> <h3>content : ${content}</h3> </body> </html> // WEB-INF/pages/delete.jsp <html> <body> <h1>Spring MVC Restful Test</h1> <h3>deleted id : ${id}</h3> </body> </html>
  • 21. 결과 (웹 브라우저) http://localhost:8080/restful/message/reset http://localhost:8080/restful/command/aa/content/111
  • 22. 결과 (리눅스/Cygwin) curl -X DELETE http://localhost:8080/restful/link/1 curl -X DELETE http://localhost:8080/restful/message/3
  • 24. Content Negotiation HTTP 1.1 스펙에서 정의 의미 media type, 언어, 문자집합, 인코딩 등에 대해 브라우저가 제공한 선호도에 따라 자원의 가장 적합한 표현을 선택. 불완전한 협상 정보를 보내는 브라우저의 요청을 지능적으로 처리하는 기능 일반적으로 다른 프로토콜을 쓰려면, request의 “type” 파라미터를 확인하고, 이에 맞는 marshalling정보를 전달해야 한다. 트위터API가 이렇게 사용되고 있음 Spring MVC에서는 한번에 해결해주는 클래스 사용 ContentNegotiatingViewResolver
  • 25. DEMO
  • 26. FruitController @Controller @RequestMapping("/fruit") public class FruitController{ @RequestMapping(value="{fruitName}", method = RequestMethod.GET) public String getFruit(@PathVariable String fruitName, ModelMap model) { Fruit fruit = new Fruit(fruitName, 1000); model.addAttribute("model", fruit); return "listfruit"; } }
  • 27. Fruit @XmlRootElement(name = "fruit") public class Fruit { String name; intquality; public Fruit() {} public Fruit(String name, int quality) { this.name = name; this.quality = quality; } @XmlElement public void setName(String name) { this.name = name; } @XmlElement public void setQuality(int quality) { this.quality = quality; } }
  • 28. mvc-dispatcher-servlet.xml <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="order" value="1" /> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> <entry key="rss" value="application/rss+xml" /> </map> </property> <property name="defaultViews"> <list> <!-- JSON View --> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> </bean> <!-- RSS View --> <bean class="com.google.rss.RssFeedView" /> <!-- JAXB XML View --> <bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <constructor-arg> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>com.google.bean.Fruit</value> </list> </property> </bean> </constructor-arg> </bean> </list> </property> <property name="ignoreAcceptHeader" value="true" /> </bean> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="order" value="2" /> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean>
  • 29. 결과 $ curl -H 'Accept: application/xml' localhost:8080/fruit/banana.xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?><fruit><name>banana</name ><quality>1000</quality></fruit> $ curl -H 'Accept: application/rss'localhost:8080/fruit/banana.rss <?xml version="1.0" encoding="UTF-8"?> <rssxmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"> <channel> <title>Sample Title</title> <link>http://google.com</link> <description>Sample Description</description> <item> <link>http://www.google.com</link> <content:encoded>banana1000</content:encoded> <author>Test</author> </item> </channel> </rss> $ curl -H 'Accept: application/json' localhost:8080/fruit/banana.json {"model":{"quality":1000,"name":"banana"}}
  • 30. Demo에서 @XmlElement사용시 유의할 점 Set메소드를 사용하려면, 다음과 같이 한다. 클래스의 멤버 필드에서 @XmlElement를 정의할 때는 set 메소드를 사용하지 않는다. @XmlRootElement(name = "fruit") public class Fruit { private String name; private int quality; @XmlElement public void setBody(Body body) { this.body= body; } public String getName() { return name; } @XmlElement public void setQuality(int quality) { this.quality= quality; } public intgetQuality() { return quality; } … } @XmlRootElement(name = "fruit") public class Fruit { @XmlElement private String name; @XmlElement private int quality; public String getName() { return name; } public intgetQuality() { return quality; } … } JAXB에서 property를 읽을 때, 잘 사용해야 하는 구조
  • 31. Demo에서 @XmlElement사용시유의할 점 Body 클래스앞에@XmlRootElement선언이 되어 있으면, Fruit 클래스 에서 @XmlElement를 사용하지 않아도 된다. @XmlRootElement(name = "body") public class Body { @XmlElement private String msg; // set/get accessory …. } @XmlRootElement(name = "fruit") public class Fruit { @XmlElement private String name; @XmlElement private int quality; private Body body; public String getName() { return name; } public intgetQuality() { return quality; } … }
  • 33. 웹 브라우져 제약 #1 GET/POST만 쓸 수 있는 웹 브라우져가 있을 수 있다. PUT과 DELETE 을 쓰기 위해서는 trick을 써야 한다. HiddenHttpMethodFilter이용 Web.xml   <filter>        <filter-name>httpMethodFilter</filter-name>        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>    </filter>        <filter-mapping>        <filter-name>httpMethodFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>
  • 34. 웹 브라우져 제약 #2 // spring mvc form tag <form:form method="delete"> <p class="submit"><input type="submit" value="Delete Pet"/></p> </form:form> @RequestMapping(method = RequestMethod.DELETE) public String deletePet(@PathVariableintownerId, @PathVariableintpetId) { this.clinic.deletePet(petId); return "redirect:/owners/" + ownerId; } 아마도 예전처럼 내부적으로 name=“_method” value=“Delete” 하는 형태로 전달하고, Spring 서버는 이 정보를 바탕으로 구현 했을 것으로 예상 <form action="POST">   <input type="hidden" id="_method" value="PUT"> </form>
  • 35. PUT/DELETE in HTML HTML version 4 과 XHTML 1에서는 HTML form안의 HTTP 요청은 GET과 POST 방식만 허용. 그동안put/delete 메소드를 사용하려면, XMLHttpRequest를 이용하였음 HTTP상에서는 ok! HTML5에서 put/delete는 사용하지 못한다고 나와 있음 http://www.w3.org/TR/html5-diff/ Using PUT and DELETE as HTTP methods for the form element is no longer supported. 참고
  • 36. 클라이언트 API : RestTemplate
  • 37. 클라이언트 API Apache Commons의 HttpClient대신 쉽게 사용할 수 있는 RestTemplate구성 <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <property name="messageConverters"> <list> <ref bean="marshallingConverter" /> <ref bean="atomConverter" /> <ref bean="jsonConverter" /> </list> </property> </bean>
  • 38. 클라이언트 API XML 요청 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_XML); HttpEntity<String> entity = new HttpEntity<String>(headers); ResponseEntity<EmployeeList> response = restTemplate.exchange( "http://localhost:8080/rest/service/emps", HttpMethod.GET, entity, EmployeeList.class); EmployeeListingemployees = response.getBody(); // handle the employees
  • 39. 클라이언트 API 새직원포스팅/ 삭제 Employee newEmp = new Employee(11, “tguest", “tguest@google.com"); HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp); restTemplate.put( "http://localhost:8080/rest/service/emp/{id}", entity, "99"); restTemplate.delete( "http://localhost:8080/rest/service/emp/{id}", "99");
  • 42. RestTemplate예제 Map<String, String> vars = new HashMap<String, String>(); vars.put("id", "111"); vars.put("content", "222"); RestTemplaterestTemplate = new RestTemplate(); String result = restTemplate.getForObject("http://localhost:8080/restful/command/{id}/content/{content}", String.class, vars); System.out.println("result : " + result); result : <html> <body> <h1>Spring MVC Restful Test</h1> <h3>command id : 111</h3> <h3>content : 222</h3> </body> </html> 결과