Spring Framework研究 RESTFUL
前言
参考文档SpringFrameworkReferenceDocumentation
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/
spring.io/guides/gs/rest-service/
http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch18s02.html
SpringFramework研究(一)RESTFUL
注:本文仅限于SpringMVC&RESTFUL于实际应用,如果想学习RESTFUL,请参考书籍:RESTful+Web+Services+Cookbook-cn.pdf、RESTFULWEBSERVICES中文版.pdf
1RESTFULHTTP服务发送地址标准
/user/HTTPGET=>查询所有的用户信息列表
/user/1HTTPGET=>查询ID=1的用户信息
/userHTTPPOST=>新增用户信息
/user/1HTTPPUT=>更新ID=1用户
/user/1HTTPDELETE=>删除ID=1用户
/user/HTTPDELETE=>删除数组IDS系列用户
JAVA控制层Action:
@Controller
@RequestMapping(value="/user")
publicclassUserController{
@ResponseBody
@RequestMapping(method=RequestMethod.GET)
publicMap<String,Object>list(
@RequestParam(value="start",defaultValue="0",required=true)Integerstart,
@RequestParam(value="limit",defaultValue="0",required=true)Integerlimit,
@RequestParam(value="name",defaultValue="",required=false)Stringname){
returnnull;
}
@ResponseBody
@RequestMapping(value="/{id}",method=RequestMethod.GET)
publicMap<String,Object>list(
@PathVariable("id")Integerid){
returnnull;
}
@ResponseBody
@RequestMapping(method=RequestMethod.POST)
publicMap<String,Object>add(
@Valid@RequestBodyUserVOvo){
returnnull;
}
@ResponseBody
@RequestMapping(value="/{id}",method=RequestMethod.PUT)
publicMap<String,Object>updateUser(
@PathVariable("id")Integerid,
@Valid@RequestBodyUserVOvo){
returnnull;
}
@ResponseBody
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
publicMap<String,Object>delete(@PathVariable("id")Integerid){
returnModelMapper.success();
}
@ResponseBody
@RequestMapping(method=RequestMethod.DELETE)
publicMap<String,Object>delete(@RequestBodyString[]ids){
returnnull;
}
}//endclassUserController
注:删除系列用户时,前台IDSJSON格式:
varids=[];
for(vari=0;i<5;i++){
ids.push(i);
}
AJAX:
$.ajax({
type:'DELETE',
url:'user/',
contentType:"application/json;charset=utf-8",
data:JSON.stringify(ids),
dataType:"json"
}
2SPring3.2RESTFULAnnotationintroduce
packagehello;
importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;
importorg.springframework.boot.SpringApplication;
importorg.springframework.context.annotation.ComponentScan;
@ComponentScan
@EnableAutoConfiguration
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}
}
@ComponentScan:The@ComponentScanannotationtellsSpringtosearchrecursivelythroughthehellopackageanditschildrenforclassesmarked
directlyorindirectlywithSpring's@Componentannotation.ThisdirectiveensuresthatSpringfindsandregisterstheGreetingController,
becauseitismarkedwith@Controller,whichinturnisakindof@Componentannotation.
@Controller
publicclassGreetingController{
privatestaticfinalStringtemplate="Hello,%s!";
privatefinalAtomicLongcounter=newAtomicLong();
@ResponseBody
@RequestMapping("/greeting")
publicGreetinggreeting(
@RequestParam(value="name",required=false,defaultValue="World")Stringname){
returnnewGreeting(counter.incrementAndGet(),
String.format(template,name));
}
}
@Controller:InSpring'sapproach(Method)tobuildingRESTfulwebservices,HTTPrequestsarehandledbyacontroller.Thesecomponentsare
easilyidentifiedbythe@Controllerannotation
@ResponseBody:Toaccomplishthis,the@ResponseBodyannotationonthegreeting()methodtellsSpringMVCthatitdoesnotneedtorender
thegreetingobjectthroughaserver-sideviewlayer,butthatinsteadthatthegreetingobjectreturnedistheresponsebody,andshould
bewrittenoutdirectly.
@RequestMapping:The@RequestMappingannotationensuresthatHTTP(specifyGETvs.PUT,POST)requeststo/greetingaremappedtothe
greeting()[email protected]@RequestMapping(method=GET)tonarrow(精密的)thismapping(映像)
@RequestBody:The@RequestBodymethodparameterannotationisusedtoindicatethatamethodparametershouldbeboundtothevalueofthe
HTTPrequestbody.Forexample,
@RequestMapping(value="/something",method=RequestMethod.PUT)
publicvoidhandle(@RequestBodyStringbody,Writerwriter)throwsIOException{
writer.write(body);
}
@PathVariable:Springusesthe@RequestMappingmethodannotationtodefinetheURITemplatefortherequest.The@PathVariableannotation
isusedtoextractthevalueofthetemplatevariablesandassigntheirvaluetoamethodvariable.ASpringcontrollermethodto
processaboveexampleisshownbelow;
@RequestMapping("/users/{userid}",method=RequestMethod.GET)
publicStringgetUser(@PathVariableStringuserId){
//implementationomitted...
}
@RequestParam:itbindsthevalueofthequerystringparameternameintothenameparameterofthegreeting()method.Thisquerystring
parameterisnotrequired;ifitisabsent(缺少)intherequest,thedefaultValueof"World"isused.
Note:AkeydifferencebetweenatraditionalMVCcontrollerandtheRESTfulwebservicecontrolleraboveisthewaythattheHTTPresponse
bodyiscreated.Ratherthanrelyingonaviewtechnologytoperformserver-siderendering渲染ofthegreetingdatatoHTML,thisRESTfulweb
servicecontrollersimplypopulatesandreturnsaGreetingobject.TheobjectdatawillbewrittendirectlytotheHTTPresponseasJSON.
AndTheGreetingobjectmustbeconvertedtoJSON.ThankstoSpring'sHTTPmessageconvertersupport,youdon'tneedtodothisconversion
manually.BecauseJackson2isontheclasspath,Spring'sMappingJackson2HttpMessageConverterisautomaticallychosentoconverttheGreeting
instancetoJSON.configurationTheSpringJsonConvertAutoLike:/项目/WebContent/WEB-INF/spring/app-config.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scanbase-package="com.test.company.web"/>
<mvc:annotation-driven>
<mvc:message-convertersregister-defaults="true">
<beanclass="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<propertyname="objectMapper">
<beanclass="com.test.security.MyObjectMapper"><propertyname="dateFormat"><beanclass="java.text.SimpleDateFormat"><constructor-argtype="java.lang.String"value="yyyy-MM-ddHH:mm:ss"/></bean></property></bean></property></bean></mvc:message-converters></mvc:annotation-driven><mvc:default-servlet-handler/></beans>
com.test.security.MyObjectMapper:
publicclassMyObjectMapperextendsObjectMapper{
privatestaticfinallongserialVersionUID=1L;
publicMyObjectMapper(){
SimpleModulesm=newSimpleModule("sm");
sm.addSerializer(String.class,newJsonSerializer<String>(){
@Override
publicvoidserialize(Stringvalue,JsonGeneratorjgen,SerializerProviderprovider)throwsIOException,JsonProcessingException{
//防止XSS
jgen.writeString(HtmlUtils.htmlEscape(value));
}
});
//当JSON转Java对象时忽略JSON中存在而Java对象中未定义的属性
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
registerModule(sm);
}
}