restful--spring
来源:互联网 发布:centos selenium 编辑:程序博客网 时间:2024/06/05 10:04
现在的系统一般不和别人交互肯定玩不起来,如果和别人交互,就要出现通信,传递信息,
第一次我及得就做了个移动的接口,当初这个疑惑啊,什么是接口,接口是什么,百度了也没人说个明白的,接口就是搭起A公司与B公司的信息传递的桥梁,由于A与B不能将所有信息共享,所以只能发布服务让客户端去调用,获取一些信息。当初看着老司机将框架搭好,上来就是一阵羡慕啊,等自己明白了才知道就是那么一会事。就是通信+数据
说了这么多直接来吧,AXIS2 、cxf这个我第一次用的,servlet(jetty)第二次用,http(封装)第三次用,dubbo(socket)第四次用,restful(增删查改)第五次个人实践
如果谁能总结更好的可以告诉我偶。
今天只说restful 这上面唯一缺点是不恩呢该直接贴图,还得导进来,麻烦,本来想去spring官网看下文档介绍,这都是介绍的啥啊,一点也不好,只能百度看一下别人的见解,自己实践了一下。
遇到的问题1 转自 http://blog.csdn.net/lijianqingfeng/article/details/36867037
用myeclipse写jsp,发现了如标题的错误,而且是报在第一行,第一行根本就没有“{”,何来的缺少“}”
心中暗骂估计又是myeclipse抽风了。
到网上一搜,发现是jsp文件中有onclick(${xxx})格式的东西,需要给${xxx}加上单引号,试了一下,果然不报错了。
遇到问题2
jquery-min.js /jquery-1.8.3.min.js引入后报错
转自 http://blog.csdn.net/pcxbest/article/details/22379667
遇到问题3
ava.lang.IllegalArgumentException: Invalid 'log4jConfigLocation' parameter: class path resource [log4j.properties] cannot be resolved to absolute file path because it does not reside in the file system
这个 问题感觉太坑爹了,由于我原来对前端接触少一办都是接触后台程序,这次读取log的配置是写在web.xml里的,配上了之后一直找不到,气的我直接<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>放到这里了。如果原来是classpath:log4j.properties 谁知道什么原因可以评论下。
顺便说下web的运行顺序,原理都是我自己写程序读取xml文件,现在web程序是直接读取web.xml,所以我直接在里面引入其他xml就可以了。
启动web会先读取web.xml里面的listener和context-param,容器创建servletcontext,其他将共享上下文
加载顺序 servletcontext--context-param---
要飞了,调试程序中还有点瑕疵,直接上代码吧,大家都知道spring下的springmvc有个controller,restful这个思想就是直接应用到springmvc上了。
配置文件 自己去看吧也可以私聊我要
/**
*
*/
package org.xdemo.example.springrestful.controller;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.xdemo.example.springrestful.entity.Person;
import org.xdemo.example.springrestful.entity.User;
/**
* @作者 Goofy
* @邮件 252878950@qq.com
* @日期 2014-4-2下午1:28:07
*/
@Controller
@RequestMapping("/user")
public class UserController {
/** 日志实例 */
private static final Logger logger = Logger.getLogger(UserController.class);
@RequestMapping(value = "/hello")
public @ResponseBody
String hello() {
return "你好!hello";
}
@RequestMapping(value = "/say/{msg}", produces = "application/json;charset=UTF-8")
public @ResponseBody
String say(@PathVariable(value = "msg") String msg) {
return "{\"msg\":\"you say:'" + msg + "'\"}";
}
// @RequestMapping(value = "/person/{id:\\d+}", method = RequestMethod.GET)
// public @ResponseBody
// Person getPerson(@PathVariable("id") int id) {
// logger.info("获取人员信息id=" + id);
// Person person = new Person();
// person.setName("张三");
// person.setSex("男");
// person.setAge(30);
// person.setId(id);
// return person;
// }
@RequestMapping(value = "/person/{id:\\d+}", method = RequestMethod.DELETE)
public @ResponseBody
String getPerson(@PathVariable("id") int id) {
logger.info("获取人员信息id=" + id);
Person person = new Person();
person.setName("张三");
person.setSex("男");
person.setAge(30);
person.setId(id);
return "person";
}
web发布了服务,ajax可以这样请求
function deleteUser(id){
$.ajax({
type: 'delete',
url:'<%=basePath%>user/'+id,
dataType:'text',
success:function(data){
if(data=="suc"){
alert("删除成功");
location.reload();
}
},
error:function(data){
}
});
}
有个项目用到了这个,竟然让他当服务端,对方只提供url,提交方式有post,get,delete等,分别对应数据的增删查改。说白了就是服务端不需要提供方法只提供uri.
public class HttpclientTest {
private static final String targetURL = "http://localhost:8100/SpringRestful/user/person/1";
public static void main(String[] args) {
URL url = null;
try {
url = new URL(targetURL);
} catch (MalformedURLException exception) {
exception.printStackTrace();
}
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
httpURLConnection.setRequestMethod("DELETE");
System.out.println(httpURLConnection.getResponseCode());
} catch (IOException exception) {
exception.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
}
我本机模范调用,但是一定要根据实际情况来看,因为请求方式就那么几个,但是请求的头部,解析啊什么的比较复杂,得注意。
终于写完了,哎,什么都得实践啊,
来一波源码
1 // org.springframework.web.bind.annotation.RequestMapping 2 @Target({ElementType.METHOD, ElementType.TYPE}) 3 @Retention(RetentionPolicy.RUNTIME) 4 @Documented 5 @Mapping 6 public @interface RequestMapping { 7 8 /** 9 * url路径,如/myPath/*.do10 */11 String[] value() default {};12 13 /**14 * HTTP request methods 如:GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.15 */16 RequestMethod[] method() default {};17 18 /**19 * requeset parameter 有3种匹配方式,是否包含某个参数,参数值相等,参数值不等于某个值,如myParam!=myValue20 */21 String[] params() default {};22 23 /**24 * request的header25 */26 String[] headers() default {};27 28 /**29 * request的MediaType30 */31 String[] consumes() default {};32 33 /**34 * response的MediaType35 */36 String[] produces() default {};37 38 }39 }
接着在这里补充吧以下内容转载自 http://blog.sina.com.cn/s/blog_72827fb10101pl9i.html-----主要是@requestMapping的参数问题
@RequestMapping 用法详解之地址映射
(2013-08-11 16:06:58)it
前段时间项目中用到了RESTful模式来开发程序,但是当用POST、PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没有加任何注解),查看了提交方式为application/json, 而且服务器端通过request.getReader() 打出的数据里确实存在浏览器提交的数据。为了找出原因,便对参数绑定(@RequestParam、 @RequestBody、 @RequestHeader 、 @PathVariable)进行了研究,同时也看了一下HttpMessageConverter的相关内容,在此一并总结。
简介:
@RequestMapping
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value:
method:
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces:
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
示例:
1、value / method 示例
默认RequestMapping("....str...")即为value的值;
- @Controller
- @RequestMapping("/appointments")
- public
class AppointmentsController { -
-
private final AppointmentBook appointmentBook; -
-
@Autowired -
public AppointmentsController(AppointmentBook appointmentBook) { -
this.appointmentBook = appointmentBook; -
} -
-
@RequestMapping(method = RequestMethod.GET) -
public Map get() { -
return appointmentBook.getAppointmentsForToday(); -
} -
-
@RequestMapping(value="/{day}", method = RequestMethod.GET) -
public Map @PathVariablegetForDay( @DateTimeFormat(iso=ISO.DATE) Date day, Model model) { -
return appointmentBook.getAppointmentsForDay(day); -
} -
-
@RequestMapping(value="/new", method = RequestMethod.GET) -
public AppointmentForm getNewForm() { -
return new AppointmentForm(); -
} -
-
@RequestMapping(method = RequestMethod.POST) -
public String @Validadd( AppointmentForm appointment, BindingResult result) { -
if (result.hasErrors()) { -
return "appointments/new"; -
} -
appointmentBook.addAppointment(appointment); -
return "redirect:/appointments"; -
} - }
value的uri值为以下三类:
A) 可以指定为普通的具体值;
B)
C) 可以指定为含正则表达式的一类值( URI Template Patterns with Regular Expressions);
example B)
- @RequestMapping(value="/owners/{ownerId}",
method=RequestMethod.GET) - public
String @PathVariablefindOwner( String ownerId, Model model) { -
Owner owner = ownerService.findOwner(ownerId); -
model.addAttribute("owner", owner); -
return "displayOwner"; - }
example C)
- @RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
-
public void handle( @PathVariableString @PathVariableversion, String extension) { -
// ... -
} - }
2 consumes、produces 示例
cousumes的样例:
- @Controller
- @RequestMapping(value
= "/pets",method "application/json")= RequestMethod.POST, consumes= - public
void addPet( @RequestBodyPet pet, Model model) { -
// implementation omitted - }
produces的样例:
- @Controller
- @RequestMapping(value
= "/pets/{petId}",method "application/json")= RequestMethod.GET, produces= - @ResponseBody
- public
Pet @PathVariablegetPet( String petId, Model model) { -
// implementation omitted - }
方法仅处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json;
3 params、headers 示例
params的样例:
- @Controller
- @RequestMapping("/owners/{ownerId}")
- public
class RelativePathUriTemplateC ontroller { -
-
@RequestMapping(value = "/pets/{petId}",method "myParam=myValue")= RequestMethod.GET, params= -
public void findPet( @PathVariableString @PathVariableownerId, String petId, Model model) { -
// implementation omitted -
} - }
headers的样例:
- @Controller
- @RequestMapping("/owners/{ownerId}")
- public
class RelativePathUriTemplateC ontroller { -
- @RequestMapping(value
= "/pets",method "Referer=http://www.ifeng.com/")= RequestMethod.GET, headers= -
public void findPet( @PathVariableString @PathVariableownerId, String petId, Model model) { -
// implementation omitted -
} - }
http://www.ifeng.com/
”的请求;
上面仅仅介绍了,RequestMapping指定的方法处理哪些请求,下面一篇将讲解怎样处理request提交的数据(数据绑定)和返回的数据。
@RequestParam @RequestBody @PathVariable 等参数绑定注解详解
(2013-08-11 16:09:23)简介:
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解:
B、处理request header部分的注解:
C、处理request body部分的注解:@RequestParam,
D、处理attribute类型是注解: @SessionAttributes, @ModelAttribute;
1、 @PathVariable
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。
示例代码:
- @Controller
- @RequestMapping("/owners/{ownerId}")
- public
class RelativePathUriTemplateC ontroller { -
-
@RequestMapping("/pets/{petId}") -
public void findPet( @PathVariableString @PathVariableownerId, String petId, Model model) { -
// implementation omitted -
} - }
2、 @RequestHeader、@CookieValue
@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。
示例代码:
这是一个Request 的header部分:
- Host
localhost:8080 - Accept
text/html,application/xhtml+xml,application/xml;q=0.9 - Accept-Language
fr,en-gb;q=0.7,en;q=0.3 - Accept-Encoding
gzip,deflate - Accept-Charset
ISO-8859-1,utf-8;q=0.7,*;q=0.7 - Keep-Alive
300
- @RequestMapping("/displayHeaderInfo.do")
- public
void displayHeaderInfo( @RequestHeader("Accept-Encoding")String encoding, -
@RequestHeader("Keep-Alive") long keepAlive) { -
-
//... -
- }
@CookieValue 可以把Request header中关于cookie的值绑定到方法的参数上。
例如有如下Cookie值:
- JSESSIONID=415A4AC178C59DACE0B2C9CA
727CDD84
- @RequestMapping("/displayHeaderInfo.do")
- public
void displayHeaderInfo( @CookieValue("JSESSIONID")String cookie) { -
-
//... -
- }
3、@RequestParam, @RequestBody
@RequestParam
A) 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String--> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;
B)用来处理Content-Type: 为 application/x-www-form-urlencoded
编码的内容,提交方式GET、POST;
C) 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定;
示例代码:
- @Controller
- @RequestMapping("/pets")
- @SessionAttributes("pet")
- public
class EditPetForm { -
-
// ... -
-
@RequestMapping(method = RequestMethod.GET) -
public String @RequestParam("petId")setupForm( int petId, ModelMap model) { -
Pet pet = this.clinic.loadPet(petId); -
model.addAttribute("pet", pet); -
return "petForm"; -
} -
-
// ...
@RequestBody
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded
编码的内容,例如application/json, application/xml等;
它是通过使用HandlerAdapter 配置的HttpMessageConverters
来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverterapplication/x-www-form-urlencoded
的内容,处理完的结果放在一个MultiValueMap里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter
示例代码:
- @RequestMapping(value
= "/something",method = RequestMethod.PUT) - public
void handle( @RequestBodyString throwsbody, Writer writer) IOException { -
writer.write(body); - }
4、@SessionAttributes, @ModelAttribute
@SessionAttributes:
该注解用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。
该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象;
示例代码:
- @Controller
- @RequestMapping("/editPet.do")
- @SessionAttributes("pet")
- public
class EditPetForm { -
// ... - }
@ModelAttribute
该注解有两个用法,一个是用于方法上,一个是用于参数上;
用于方法上时:
用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;要绑定的值来源于:
A) @SessionAttributes 启用的attribute 对象上;
B) @ModelAttribute 用于方法上时指定的model对象;
C) 上述两种情况都没有时,new一个需要绑定的bean对象,然后把request中按名称对应的方式把值绑定到bean中。
用到方法上@ModelAttribute的示例代码:
- //
Add one attribute - //
The return value of the method is added to the model under the name "account" - //
You can customize the name via @ModelAttribute("myAccount") -
- @ModelAttribute
- public
Account @RequestParamaddAccount( String number) { -
return accountManager.findAccount(number); - }
这种方式实际的效果就是在调用@RequestMapping的方法之前,为request对象的model里put(“account”, Account);
用在参数上的@ModelAttribute示例代码:
- @RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit",
method = RequestMethod.POST) - public
String @ModelAttributeprocessSubmit( Pet pet) { -
- }
补充讲解:
问题: 在不给定注解的情况下,参数是怎样绑定的?
通过分析AnnotationMethodHandlerA
若要绑定的对象时简单类型:
若要绑定的对象时复杂类型:
这里的简单类型指java的原始类型(boolean, int 等)、原始类型对象(Boolean, Int等)、String、Date等ConversionService里可以直接String转换成目标对象的类型;
下面贴出AnnotationMethodHandlerA
- private
Object[] resolveHandlerArguments(Method handlerMethod, Object handler, -
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception { -
-
Class[] paramTypes = handlerMethod.getParameterTypes(); -
Object[] args = new Object[paramTypes.length]; -
-
for ( inti 0;= i < args.length; i++) { -
MethodParameter methodParam = new MethodParameter(handlerMethod, i); -
methodParam.initParameterNameDiscove ry(this.parameterNameDiscoverer); -
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass()); -
String paramName = null; -
String headerName = null; -
boolean requestBodyFound false;= -
String cookieName = null; -
String pathVarName = null; -
String attrName = null; -
boolean required false;= -
String defaultValue = null; -
boolean validate false;= -
Object[] validationHints = null; -
int annotationsFound 0;= -
Annotation[] paramAnns = methodParam.getParameterAnnotations(); -
-
for (Annotation paramAnn : paramAnns) { -
if (RequestParam. class.isInstance(paramAnn)){ -
RequestParam requestParam = (RequestParam) paramAnn; -
paramName = requestParam.value(); -
required = requestParam.required(); -
defaultValue = parseDefaultValueAttribu te(requestParam.defaultValue()); -
annotationsFound++; -
} -
else if (RequestHeader. class.isInstance(paramAnn)){ -
RequestHeader requestHeader = (RequestHeader) paramAnn; -
headerName = requestHeader.value(); -
required = requestHeader.required(); -
defaultValue = parseDefaultValueAttribu te(requestHeader.defaultValue()); -
annotationsFound++; -
} -
else if (RequestBody. class.isInstance(paramAnn)){ -
requestBodyFound = true; -
annotationsFound++; -
} -
else if (CookieValue. class.isInstance(paramAnn)){ -
CookieValue cookieValue = (CookieValue) paramAnn; -
cookieName = cookieValue.value(); -
required = cookieValue.required(); -
defaultValue = parseDefaultValueAttribu te(cookieValue.defaultValue()); -
annotationsFound++; -
} -
else if (PathVariable. class.isInstance(paramAnn)){ -
PathVariable pathVar = (PathVariable) paramAnn; -
pathVarName = pathVar.value(); -
annotationsFound++; -
} -
else if (ModelAttribute. class.isInstance(paramAnn)){ -
ModelAttribute attr = (ModelAttribute) paramAnn; -
attrName = attr.value(); -
annotationsFound++; -
} -
else if (Value. class.isInstance(paramAnn)){ -
defaultValue = ((Value) paramAnn).value(); -
} -
else if (paramAnn.annotationType().getSimpleName().startsWith( "Valid")){ -
validate = true; -
Object value = AnnotationUtils.getValue(paramAnn); -
validationHints = (value instanceof Object[] new? (Object[]) value : Object[] {value}); -
} -
} -
-
if (annotationsFound 1)> { -
throw new IllegalStateException( "Handlerparameter annotations are exclusive choices - " + -
"do not specify more than one such annotation on the same parameter: " + handlerMethod); -
} -
-
if (annotationsFound 0)== { //若没有发现注解 -
Object argValue = resolveCommonArgument(methodParam, webRequest); //判断WebRquest是否可赋值给参数 -
if (argValue != WebArgumentResolver.UNRESOLVED) { -
args[i] = argValue; -
} -
else if (defaultValue null)!= { -
args[i] = resolveDefaultValue(defaultValue); -
} -
else { -
Class
- restful--spring
- Spring RESTful
- Spring +restful 构造webservice
- spring restful实践(一)
- spring restful实践(二)
- Spring与RESTful
- Spring +restful 构造webservice
- Restful Spring MVC
- Spring Restful 风格示例
- Spring MVC Restful
- Restful Spring MVC
- spring restful注解
- Spring restful 配置
- spring+restful service
- Spring 支持 RESTful 功能
- spring mvc Restful架构
- Spring之restful
- spring MVC 乱码、restful
- UVA-10474 Where is the Marble?
- 青蛙跳台阶问题
- POJ 2369Permutations
- hdoj--1862 EXCEL排序(sort+结构体)
- * **ACM错误总结
- restful--spring
- linux常用的一些命令(一)
- 【杭电-oj】-2803-The MAX(sort快排)
- UVA-152 Tree's a Crowd
- Java ExecutorService四种线程池的例子与说明
- LeetCode Guess Number Higher or Lower
- El表达式
- Dubins路径及航迹跟踪控制
- SIGCHLD信号