转载自:http://blog.csdn.net/walkerjong/article/details/7946109

学习了下,对@RequestBody,@SessionAttributes,@ModelAttribute还不是很了解,继续学习,也望知道的能告诉我一下,谢谢。

简介:

handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)

A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解:   @PathVariable;

B、处理request header部分的注解:   @RequestHeader, @CookieValue;

C、处理request body部分的注解:@RequestParam,  @RequestBody;

D、处理attribute类型是注解: @SessionAttributes, @ModelAttribute;

1、 @PathVariable

当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。

示例代码:

  1. @Controller
  2. @RequestMapping("/owners/{ownerId}")
  3. publicclass RelativePathUriTemplateController
    {
  4. @RequestMapping("/pets/{petId}")
  5. publicvoid findPet(@PathVariable String
    ownerId, @PathVariable String petId,
    Model model) {
  6. // implementation
    omitted
  7. }
  8. }
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController { @RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}

上面代码把URI template 中变量 ownerId的值和petId的值,绑定到方法的参数上。若方法参数名称和需要绑定的uri template中变量名称不一致,需要在@PathVariable("name")指定uri template中的名称。

2、 @RequestHeader、@CookieValue

@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。

示例代码:

这是一个Request 的header部分:

  1. Host                    localhost:8080
  2. Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
  3. Accept-Language         fr,en-gb;q=0.7,en;q=0.3
  4. Accept-Encoding         gzip,deflate
  5. Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
  6. Keep-Alive              300
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
  1. @RequestMapping("/displayHeaderInfo.do")
  2. publicvoid displayHeaderInfo(@RequestHeader("Accept-Encoding")
    String encoding,
  3. @RequestHeader("Keep-Alive") long keepAlive) 
    {
  4. //...
  5. }
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) { //... }

上面的代码,把request header部分的 Accept-Encoding的值,绑定到参数encoding上了, Keep-Alive header的值绑定到参数keepAlive上。

@CookieValue 可以把Request header中关于cookie的值绑定到方法的参数上。

例如有如下Cookie值:

  1. JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

参数绑定的代码:

  1. @RequestMapping("/displayHeaderInfo.do")
  2. publicvoid displayHeaderInfo(@CookieValue("JSESSIONID")
    String cookie)  {
  3. //...
  4. }
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) { //... }

即把JSESSIONID的值绑定到参数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用来指示参数是否必须绑定;

示例代码:

  1. @Controller
  2. @RequestMapping("/pets")
  3. @SessionAttributes("pet")
  4. publicclass EditPetForm
    {
  5. // ...
  6. @RequestMapping(method
    = RequestMethod.GET)
  7. public String
    setupForm(@RequestParam("petId") int petId,
    ModelMap model) {
  8. Pet pet = this.clinic.loadPet(petId);
  9. model.addAttribute("pet",
    pet);
  10. return"petForm";
  11. }
  12. // ...
@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm { // ... @RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") 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上的。

因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;

示例代码:

  1. @RequestMapping(value
    = "/something", method = RequestMethod.PUT)
  2. publicvoid handle(@RequestBody String
    body, Writer writer) throws IOException
    {
  3. writer.write(body);
  4. }
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
writer.write(body);
}

4、@SessionAttributes, @ModelAttribute

@SessionAttributes:

该注解用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。

该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象;

示例代码:

  1. @Controller
  2. @RequestMapping("/editPet.do")
  3. @SessionAttributes("pet")
  4. publicclass EditPetForm
    {
  5. // ...
  6. }
@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
// ...
}

@ModelAttribute

该注解有两个用法,一个是用于方法上,一个是用于参数上;

用于方法上时:  通常用来在处理@RequestMapping之前,为请求绑定需要从后台查询的model;

用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;要绑定的值来源于:

A) @SessionAttributes 启用的attribute 对象上;

B) @ModelAttribute 用于方法上时指定的model对象;

C) 上述两种情况都没有时,new一个需要绑定的bean对象,然后把request中按名称对应的方式把值绑定到bean中。

用到方法上@ModelAttribute的示例代码:

  1. // Add one attribute
  2. // The return value
    of the method is added to the model under the name "account"
  3. // You can customize
    the name via @ModelAttribute("myAccount")
  4. @ModelAttribute
  5. public Account
    addAccount(@RequestParam String number)
    {
  6. return accountManager.findAccount(number);
  7. }
// 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 addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}

这种方式实际的效果就是在调用@RequestMapping的方法之前,为request对象的model里put(“account”, Account);

用在参数上的@ModelAttribute示例代码:

  1. @RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit",
    method = RequestMethod.POST)
  2. public String
    processSubmit(@ModelAttribute Pet pet)
    {
  3. }
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) { }

首先查询 @SessionAttributes有无绑定的Pet对象,若没有则查询@ModelAttribute方法层面上是否绑定了Pet对象,若没有则将URI template中的值按对应的名称绑定到Pet对象的各属性上。

补充讲解:

问题: 在不给定注解的情况下,参数是怎样绑定的?

通过分析AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter的源代码发现,方法的参数在不给定参数的情况下:

若要绑定的对象时简单类型:  调用@RequestParam来处理的。

若要绑定的对象时复杂类型:  调用@ModelAttribute来处理的。

这里的简单类型指java的原始类型(boolean, int 等)、原始类型对象(Boolean, Int等)、String、Date等ConversionService里可以直接String转换成目标对象的类型;

下面贴出AnnotationMethodHandlerAdapter中绑定参数的部分源代码:

  1. private Object[]
    resolveHandlerArguments(Method handlerMethod, Object handler,
  2. NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception
    {
  3. Class[] paramTypes = handlerMethod.getParameterTypes();
  4. Object[] args = new Object[paramTypes.length];
  5. for (int i
    = 0; i < args.length; i++) {
  6. MethodParameter methodParam = new MethodParameter(handlerMethod,
    i);
  7. methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
  8. GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
  9. String paramName = null;
  10. String headerName = null;
  11. boolean requestBodyFound
    = false;
  12. String cookieName = null;
  13. String pathVarName = null;
  14. String attrName = null;
  15. boolean required
    = false;
  16. String defaultValue = null;
  17. boolean validate
    = false;
  18. Object[] validationHints = null;
  19. int annotationsFound
    = 0;
  20. Annotation[] paramAnns = methodParam.getParameterAnnotations();
  21. for (Annotation
    paramAnn : paramAnns) {
  22. if (RequestParam.class.isInstance(paramAnn))
    {
  23. RequestParam requestParam = (RequestParam) paramAnn;
  24. paramName = requestParam.value();
  25. required = requestParam.required();
  26. defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
  27. annotationsFound++;
  28. }
  29. elseif (RequestHeader.class.isInstance(paramAnn))
    {
  30. RequestHeader requestHeader = (RequestHeader) paramAnn;
  31. headerName = requestHeader.value();
  32. required = requestHeader.required();
  33. defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
  34. annotationsFound++;
  35. }
  36. elseif (RequestBody.class.isInstance(paramAnn))
    {
  37. requestBodyFound = true;
  38. annotationsFound++;
  39. }
  40. elseif (CookieValue.class.isInstance(paramAnn))
    {
  41. CookieValue cookieValue = (CookieValue) paramAnn;
  42. cookieName = cookieValue.value();
  43. required = cookieValue.required();
  44. defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
  45. annotationsFound++;
  46. }
  47. elseif (PathVariable.class.isInstance(paramAnn))
    {
  48. PathVariable pathVar = (PathVariable) paramAnn;
  49. pathVarName = pathVar.value();
  50. annotationsFound++;
  51. }
  52. elseif (ModelAttribute.class.isInstance(paramAnn))
    {
  53. ModelAttribute attr = (ModelAttribute) paramAnn;
  54. attrName = attr.value();
  55. annotationsFound++;
  56. }
  57. elseif (Value.class.isInstance(paramAnn))
    {
  58. defaultValue = ((Value) paramAnn).value();
  59. }
  60. elseif (paramAnn.annotationType().getSimpleName().startsWith("Valid"))
    {
  61. validate = true;
  62. Object value = AnnotationUtils.getValue(paramAnn);
  63. validationHints = (value instanceof Object[]
    ? (Object[]) value : new Object[]
    {value});
  64. }
  65. }
  66. if (annotationsFound
    > 1) {
  67. thrownew IllegalStateException("Handler
    parameter annotations are exclusive choices - " +
  68. "do
    not specify more than one such annotation on the same parameter: " + handlerMethod);
  69. }
  70. if (annotationsFound
    == 0) {//
    若没有发现注解
  71. Object argValue = resolveCommonArgument(methodParam, webRequest);    //判断WebRquest是否可赋值给参数
  72. if (argValue
    != WebArgumentResolver.UNRESOLVED) {
  73. args[i] = argValue;
  74. }
  75. elseif (defaultValue
    != null)
    {
  76. args[i] = resolveDefaultValue(defaultValue);
  77. }
  78. else {
  79. Class<?> paramType = methodParam.getParameterType();
  80. if (Model.class.isAssignableFrom(paramType)
    || Map.class.isAssignableFrom(paramType))
    {
  81. if (!paramType.isAssignableFrom(implicitModel.getClass()))
    {
  82. thrownew IllegalStateException("Argument
    [" + paramType.getSimpleName() + "]
    is of type " +
  83. "Model
    or Map but is not assignable from the actual model. You may need to switch " +
  84. "newer
    MVC infrastructure classes to use this argument.");
  85. }
  86. args[i] = implicitModel;
  87. }
  88. elseif (SessionStatus.class.isAssignableFrom(paramType))
    {
  89. args[i] = this.sessionStatus;
  90. }
  91. elseif (HttpEntity.class.isAssignableFrom(paramType))
    {
  92. args[i] = resolveHttpEntityRequest(methodParam, webRequest);
  93. }
  94. elseif (Errors.class.isAssignableFrom(paramType))
    {
  95. thrownew IllegalStateException("Errors/BindingResult
    argument declared " +
  96. "without
    preceding model attribute. Check your handler method signature!");
  97. }
  98. elseif (BeanUtils.isSimpleProperty(paramType))
    {// 判断是否参数类型是否是简单类型,若是在使用@RequestParam方式来处理,否则使用@ModelAttribute方式处理
  99. paramName = "";
  100. }
  101. else {
  102. attrName = "";
  103. }
  104. }
  105. }
  106. if (paramName
    != null)
    {
  107. args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
  108. }
  109. elseif (headerName
    != null)
    {
  110. args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
  111. }
  112. elseif (requestBodyFound)
    {
  113. args[i] = resolveRequestBody(methodParam, webRequest, handler);
  114. }
  115. elseif (cookieName
    != null)
    {
  116. args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
  117. }
  118. elseif (pathVarName
    != null)
    {
  119. args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
  120. }
  121. elseif (attrName
    != null)
    {
  122. WebDataBinder binder =
  123. resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
  124. boolean assignBindingResult
    = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i
    + 1]));
  125. if (binder.getTarget()
    != null)
    {
  126. doBind(binder, webRequest, validate, validationHints, !assignBindingResult);
  127. }
  128. args[i] = binder.getTarget();
  129. if (assignBindingResult)
    {
  130. args[i + 1]
    = binder.getBindingResult();
  131. i++;
  132. }
  133. implicitModel.putAll(binder.getBindingResult().getModel());
  134. }
  135. }
  136. return args;
  137. }
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception { Class[] paramTypes = handlerMethod.getParameterTypes();
Object[] args = new Object[paramTypes.length]; for (int i = 0; i < args.length; i++) {
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
methodParam.initParameterNameDiscovery(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 = parseDefaultValueAttribute(requestParam.defaultValue());
annotationsFound++;
}
else if (RequestHeader.class.isInstance(paramAnn)) {
RequestHeader requestHeader = (RequestHeader) paramAnn;
headerName = requestHeader.value();
required = requestHeader.required();
defaultValue = parseDefaultValueAttribute(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 = parseDefaultValueAttribute(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[] ? (Object[]) value : new Object[] {value});
}
} if (annotationsFound > 1) {
throw new IllegalStateException("Handler parameter 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<?> paramType = methodParam.getParameterType();
if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
if (!paramType.isAssignableFrom(implicitModel.getClass())) {
throw new IllegalStateException("Argument [" + paramType.getSimpleName() + "] is of type " +
"Model or Map but is not assignable from the actual model. You may need to switch " +
"newer MVC infrastructure classes to use this argument.");
}
args[i] = implicitModel;
}
else if (SessionStatus.class.isAssignableFrom(paramType)) {
args[i] = this.sessionStatus;
}
else if (HttpEntity.class.isAssignableFrom(paramType)) {
args[i] = resolveHttpEntityRequest(methodParam, webRequest);
}
else if (Errors.class.isAssignableFrom(paramType)) {
throw new IllegalStateException("Errors/BindingResult argument declared " +
"without preceding model attribute. Check your handler method signature!");
}
else if (BeanUtils.isSimpleProperty(paramType)) {// 判断是否参数类型是否是简单类型,若是在使用@RequestParam方式来处理,否则使用@ModelAttribute方式处理
paramName = "";
}
else {
attrName = "";
}
}
} if (paramName != null) {
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
}
else if (headerName != null) {
args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
}
else if (requestBodyFound) {
args[i] = resolveRequestBody(methodParam, webRequest, handler);
}
else if (cookieName != null) {
args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
}
else if (pathVarName != null) {
args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
}
else if (attrName != null) {
WebDataBinder binder =
resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
if (binder.getTarget() != null) {
doBind(binder, webRequest, validate, validationHints, !assignBindingResult);
}
args[i] = binder.getTarget();
if (assignBindingResult) {
args[i + 1] = binder.getBindingResult();
i++;
}
implicitModel.putAll(binder.getBindingResult().getModel());
}
} return args;
}

RequestMappingHandlerAdapter中使用的参数绑定,代码稍微有些不同,有兴趣的同仁可以分析下,最后处理的结果都是一样的。

示例:

  1. @RequestMapping ({"/", "/home"})
  2. public String
    showHomePage(String key){
  3. logger.debug("key="+key);
  4. return"home";
  5. }
@RequestMapping ({"/", "/home"})
public String showHomePage(String key){ logger.debug("key="+key); return "home";
}

这种情况下,就调用默认的@RequestParam来处理。

  1. @RequestMapping (method
    = RequestMethod.POST)
  2. public String
    doRegister(User user){
  3. if(logger.isDebugEnabled()){
  4. logger.debug("process
    url[/user], method[post] in "+getClass());
  5. logger.debug(user);
  6. }
  7. return"user";
  8. }
	@RequestMapping (method = RequestMethod.POST)
public String doRegister(User user){
if(logger.isDebugEnabled()){
logger.debug("process url[/user], method[post] in "+getClass());
logger.debug(user);
} return "user";
}

这种情况下,就调用@ModelAttribute来处理。

参考文档:

1、 Spring Web Doc:

spring-3.1.0/docs/spring-framework-reference/html/mvc.html

@RequestParam @RequestBody @PathVariable 等参数绑定注解详解()的更多相关文章

  1. 【转】@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解 2014-06-02 11:24 23683人阅读 评论(2) 收藏 举报 目录(?)[+] 引言 ...

  2. @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    文章主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用. 简介: handler method 参数绑定常用的注解,我们根据他们处理的Request ...

  3. Spring @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    背景 昨天一个人瞎倒腾spring boot,然后遇到了一点问题,所以把这个问题总结一下. 主要讲解request 数据到handler method 参数数据的绑定,所用到的注解和什么情形下使用. ...

  4. 11.@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: handler method ...

  5. @RequestParam @RequestBody @PathVariable 等参数绑定注解详解(转)

    引言: 接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: han ...

  6. (转)@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    引言: 接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: han ...

  7. springmvc @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    简介: handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型) A.处理requet uri 部分(这里指uri templat ...

  8. 转载:@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    转载自:https://blog.csdn.net/walkerjong/article/details/7946109#commentBox   因为写的很好很全,所以转载过来 引言:接上一篇文章, ...

  9. SpringMVC @RequestBody @RequestParam @PathVariable 等参数绑定注解详解

    request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: http://blog.csdn.net/walkerjong/article/details/794 ...

  10. @PathVariable @RequestParam @RequestBody等参数绑定注解详解

    一.分类 handler method 参数绑定常用的注解,我们根据他们处理的Request的内容不同分为四类: 处理request uri 部分的注解:   @PathVariable;(这里指ur ...

随机推荐

  1. PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践

    大家好,我是码农先森. 我们在某宝或某多多上抢购商品时,如果只是下了订单但没有进行实际的支付,那在订单页面会有一个支付倒计时,要是过了这个时间点那么订单便会自动取消.在这样的业务场景中,一般情况下就会 ...

  2. psutil 检测exe是否已经运行

    安装依赖 pip install psutil 代码 import psutil def check_if_process_running(process_name): ''' Check if th ...

  3. Coursera, Big Data 5, Graph Analytics for Big Data, Week 4

    Graph Analytics With Neo4j 讲了怎样用Cypher 脚本语言去操作 Neo4j, 包括加graph, 导入csv数据. 接着讲了一些neo4j 的基本操作. 最后讲的,pat ...

  4. 总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景

    总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景 redis 和memcached 有什么区别?为什么在高并发下,单线程的redis 比多线程的效率高? mc 可以缓存图片和视频,re ...

  5. CSS & JS Effect – 用 wheel 模拟 scroll

    前言 在 用 JavaScript 实现 position sticky 文章中,我提到了用 wheel 来模拟 scroll 效果. 这篇来说说具体怎么实现,挺简单的哦. Preparation t ...

  6. EF Core – 乐观并发

    前言 之前写过 EF Core 悲观并发, 这篇主要讲一下乐观并发. 乐观并发的机制可以看这篇. Why Need This? 如果你用 EF Core 做数据管理, 建议你每个 Entity 都配置 ...

  7. 主流流媒体的综合性能大 PK ( smart_rtmpd, srs, zlm, nginx rtmp )

    简述 随着互联网的发展,音视频行业越来越火,自然而然的流媒体服务器也是百花齐放.市面上也有很多种类的流媒体服务器,让人眼花缭乱.特别是对技术了解不深的朋友,更不知道怎么选择. 其实作为服务器,主要考察 ...

  8. 大一下的acm生活

    在一个名气不大的211学校刷题的日常. 感觉这些算法题好难啊! 最近有好多实验室要招新,不知道该怎么办,自己只想就业,并不想升学,好烦! 真枯燥,好无聊. 现在要学习相关的网页设计和网站建设,例如配色 ...

  9. BFS 马的遍历————洛谷p1443

    马的遍历 题目描述 有一个 \(n \times m\) 的棋盘,在某个点 \((x, y)\) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步. 输入格式 输入只有一行四个整数,分别为 ...

  10. 暑假集训CSP提高模拟1

    A.Start 比较小的大模拟,还没改出来 B.mine 线性推一下(这个题记搜容易写偏,因为分讨太多) 设 \(f[i][j]\),第一维表示位置,第二位表示末位状态(是雷,是 \(0\),是 \( ...