Spring MVC可以同时接收getget 和postt方式传递的参数吗

2013年3月 总版技术专家分月排行榜第二
2014年2月 Java大版内专家分月排行榜第一2013年8月 Java大版内专家分月排行榜第一2013年5月 Java大版内专家分月排行榜第一2013年4月 Java大版内专家分月排行榜第一2013年3月 Java大版内专家分月排行榜第一2013年2月 Java大版内专家分月排行榜第一
2016年1月 Java大版内专家分月排行榜第一2015年12月 Java大版内专家分月排行榜第一2015年9月 Java大版内专家分月排行榜第一2015年8月 Java大版内专家分月排行榜第一
2016年3月 Java大版内专家分月排行榜第二2016年2月 Java大版内专家分月排行榜第二2015年11月 Java大版内专家分月排行榜第二2015年10月 Java大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。SpringMVC数据传输的过程 - 简书
SpringMVC数据传输的过程
这个主题其实想了解下SpringMVC的两种不同的参数提交方式和接受方式。
SpringMVC的数据流程图:
c78874dd-1edf-5fee235db4.png
Jsp页面提交的参数信息----》http请求----》DispatcherServlet---》controller(接受方式直接就是对象)---》View(也是一个对象下的属性)解答如何将http请求中的参数直接转变成为对应的对象的。
jsp数据绑定----spring data binder
15.50.53.png
Servlet中的输入参数为都是string类型,而spring mvc通过data bind机制将这些string 类型的输入参数转换为相应的command object(根据view和controller之间传输数据的具体逻辑,也可称为model attributes, domain model objects)。在这个转换过程中,spring实际是先利用java.beans.PropertyEditor中的 setAdText方法来把string格式的输入转换为bean属性, 亦可通过继承java.beans.PropertyEditorSupport来实现自定义的PropertyEditors,具体实现方式可参考spring reference 3.0.5 第 5.4节中的 Registering additional custom PropertyEditors部分。 自定义完毕propertyEditor后,有以下几种方式来注册自定义的customer propertyEditor.
WebDataBinder 这个类文件
* Special {@link DataBinder} for data binding from web request parameters
* to JavaBean objects. Designed for web environments, but not dependent on
* the Servlet API; serves as base class for more specific DataBinder variants,
* such as {@link org.springframework.web.bind.ServletRequestDataBinder}.
对于requestBody或httpEntity中数据的类型转换 Spring MVC中对于requestBody中发送的数据转换不是通过databind来实现,而是使用HttpMessageConverter来实现具体的类型转换。 例如,之前提到的json格式的输入,在将json格式的输入转换为具体的model的过程中,spring mvc首先找出request header中的contenttype,再遍历当前所注册的所有的HttpMessageConverter子类, 根据子类中的canRead()方法来决定调用哪个具体的子类来实现对requestBody中的数据的解析。如果当前所注册的httpMessageConverter中都无法解析对应contexttype类型,则抛出HttpMediaTypeNotSupportedException (http 415错误)。 那么需要如何注册自定义的messageConverter呢,很不幸,在spring 3.0.5中如果使用annotation-driven的配置方式的话,无法实现自定义的messageConverter的配置,必须老老实实的自己定义AnnotationMethodHandlerAdapter的bean定义,再设置其messageConverters以注册自定义的messageConverter。 在3.1版本中,将增加annotation-driven对自定义的messageConverter的支持 (SPR-7504)。1 form表单提交的方式可以直接通过WebDataBinder方式进行数据转换,将http body中的属性值注入到对象中。下面代码是我的controller层里接受数据的方式:Object
@RequiresPermissions("sys:role:add")
@RequestMapping(value = "create", method = RequestMethod.POST)
@ResponseBody
public Map&String, Object& create(@Valid SysRole role, Model model) {
roleService.insert(role);
return responseSuccessMessage();
2 不在form表单提交,通过body中的json数据提交的方式:
@RequestMapping(value = "updateData", method = RequestMethod.POST,produces="application/charset=UTF-8")
@ResponseBody
public Map&String, Object& updateData(@RequestBody BerInsuranceTypeEmail rowData,HttpServletRequest request) {
berInsuranceTypeEmailService.update(rowData);
return responseSuccessMessage();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return responseFailMessage();
这里继续进行分析这两种方式的不同点以及所用到技术的方便之处和难点,1 首先第一种方式form表单提交方式:先看一段代码(这是form表单提交的方式以及在浏览器端获取到的请求信息),可以明显的看出来其实我们的普通form表单提交的方式是$.post
* ajax post data
ajaxPostData = function(submitUrl, submitParam, callback, dataType){
console.log(submitUrl,submitParam,callback,dataType);
if(dataType==undefined){
dataType = "json";
$.post(encodeURI(submitUrl),submitParam, callback,dataType);
09.46.29.png
2 第二种方式:使用ajax的提交方式。
function updateRow(rowIndex, rowData, changes){
/* rowData是选择的当前代码
change是改变的的代码
(rowData);
(changes); */
//alert(JSON.stringify(rowData));
$.fn.datagrid.extensions.onAfterEdit.apply(this, arguments);
async:true,
type:'POST',
data:JSON.stringify(rowData),
contentType:'text/charset=utf-8',
url:"${ctx}/a/system/BerTypeEmail/updateData",
success: function(data){
$('#dg').datagrid('reload');
successTipEx(data);
09.25.55.png
这里是我的后台controller的接收方式,其实是在SpringMVC的拦截器重进行了相应的数据转换HttpMessageConverters(后面会单独介绍):
@RequestMapping(value = "updateData", method = RequestMethod.POST,produces="application/charset=UTF-8")
@ResponseBody
public Map&String, Object& updateData(@RequestBody BerInsuranceTypeEmail rowData,HttpServletRequest request) {
berInsuranceTypeEmailService.update(rowData);
return responseSuccessMessage();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return responseFailMessage();
那么问题又来了,我们这两种提交的方式中HTTP请求中的form data和request payload的区别在哪里???
What is the difference between form data and request payload?:
When I send an AJAX Post request and send parameters in queryString in send() method,
Chrome Developer Tool’s XHR capture tool shows the parameters under request payload.
and when I use jquery’s post function, The tool shows parameters under Form Data section.
What is the difference ?
you have not provided enough information how you use the send function,
but I assume that you do not set mime type to specify you are sending form data
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
the data sent are in this case encoded as you encode a query string
xhr.send("name=foo&value=bar");
otherwise it will not be interpreted as form data by Developer Tools.
jquery does majority of work for you in this regard.
关键就是设置Content-type这个Header为application/x-www-form-urlencoded,实际上对于常规的HTML页面上的form的Content-type默认就是这个值。
相似的问题还发生在AngularJS的$http方法中,How can I make angular.js post data as form data instead of a request payload? 这个问题竟然有77个“顶”,看来遇到此问题的人还真不少。
注:这个问题里说jQuery的ajax方法是可以的,我今天遇到是不可以的,这个需要再验证一下。
当然解决的方法是一样的:
method: 'POST',
data: xsrf,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
解决疑惑的网址:
具体的处理办法就是在我们的ajax请求中headers: {'Content-Type':'application/x-www-form-urlencoded'}这里还需要做实验进行测试才行。还有一个问题是ajax提交方式和post提交方式有所不同,用jQuery的ajax方法和post方法分别发送请求,在后台Servlet进行处理时结果是不一样的,比如用$.ajax方法发送请求时(data参数是一个JSON.stringify()处理后的字符串,而不是一个JSON对象)但此时是不可用request.getParam(key) 来取值的。如果用$.post方法来发送请求(data参数是一个JSON对象,而不要再用JSON.stringify()处理为字符串了),结果恰恰相反。
@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用来指示参数是否必须绑定;示例代码:
@RequiresPermissions("sys:productInfo:edit")
@RequestMapping(value = "update", method = RequestMethod.POST)
@ResponseBody
public Map&String, Object& update(@RequestParam(value = "files") MultipartFile
files[],String paymentId,HttpServletRequest request,HttpServletResponse response,@Valid BemProductInfo productInfo, Model model) {
BemProductInfo productInfo1 = new BemProductInfo();
productInfo1 = productInfoService.getEntityById(productInfo.getId());
for (int i = 0; i & files. i++) {
MultipartFile file =files[i];
@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&里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageC示例代码:
@RequestMapping(value = "updateData", method = RequestMethod.POST,produces="application/charset=UTF-8")
@ResponseBody
public Map&String, Object& updateData(@RequestBody BerInsuranceTypeEmail rowData,HttpServletRequest request) {
berInsuranceTypeEmailService.update(rowData);
return responseSuccessMessage();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return responseFailMessage();
SpringMVC的特性
REST功能是Spring MVC 3.0新增的,它通过不带扩展名的URL来访问系统资源。REST是把访问的所有资源看成静态的,一个或一组,每个不同的URL地址都是一个静态资源。那么Spring MVC 3.0是如何支持REST的呢?简单的说,它是通过@RequestMapping及@PathVariable注解提供的,在@RequestMapping中指定value与method,就可以处理对应的请求。
SpringMVC如何关联Controller和View的
这里关注下ViewResolver的组件和View组件之间的关联
&!-- jsp文件配置 --&
&!-- 视图解析器 --&
&bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&
&property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /&
&property name="prefix" value="/WEB-INF/jsp/"&&/property&
&property name="suffix" value=".jsp"&&/property&
这个定义的含义是指UrlBasedViewResolver将使用JstlView对象来渲染结果,并将handler method返回的modelAndView基础上,
加上目录前缀/WEB-INF/jsp/和文件名称后缀.jsp。例如结果返回的viewName为hello world,
则对应的实际jsp为/WEB-INF/jsp/helloworld.jsp
当返回的viewName的前缀为forward:时,spring mvc将结果通过forward的方式转到对应的视图,
例如forward:helloworld。这也是spring mvc缺省的使用模式。
当返回的viewName的前缀为redirect:时,spring mvc将结果通过redirect的方式转到对应的视图。
例如redirect:hello world
InternalResourceViewResolver为UrlBasedViewResolver的子类,它将InternalResourceView作为缺省的View类,
如果当前classpath中有jstl的jar包时则使用JstlView作为缺省的view来渲染结果。
因此以下使用InternalResourceViewResolver的定义应该和之前使用UrlBasedViewResolver定义的viewresolver的作用相同。
SpringMVC的逻辑结构图
springmvc_flow.jpg
1、Spring MVC的核心是DispatcherServlet,当客户端发送一个请求时,这个请求经过一系列过滤器处理。然后DispatcherServlet会接收到这个请求。
2、DispatcherServlet会从HandlerMapping对象中查找与请求匹配的Controller,并将结果返回给DispatcherServlet。
3、DispatcherServlet将请求转发给目标Controller,如果定义有拦截器,则会经过这些拦截器处理。
4、标Controller处理完成业务逻辑后,会返回一个结果给DispatcherServlet。
5、DispatcherServlet根据结果查询ViewResolver,找到与之对应的视图对象,同样将结果返回给DispatcherServlet。
6、DispatcherServlet根据指定的显示结果,调用模板对象渲染view。
7、将view返回给客户端。
根据上面的说明,可以很很明显的看出,Spring MVC的核心是Servlet,并且创建的Controller其实也是一个Servlet。
swift初学者,有意于IOS开发Spring MVC可以同时接收get和post方式传递的参数吗?
Spring MVC可以同时接收get和post方式传递的参数吗?
method什么都不写,就是全支持.
--- 共有 1 条评论 ---
引用来自“CrazyHarry”的评论@RequestMapping(value = &/test&, method = { RequestMethod.GET, RequestMethod.POST }, produce=&application/json&)
public @ResponseBody Something query(@RequestBody Something some,HttpServletRequest request, HttpServletResponse response){
直接明了,搞定了,一直以为不可以一起接收呢,还有很大的进步空间啊!
--- 共有 1 条评论 ---
不写method,本身就是默认全部接收的。哎,没想到一个习以为常的东西,竟然会成了一个问题,是否是你们想太多了吗
@RequestMapping(value = &/test&, method = { RequestMethod.GET, RequestMethod.POST }, produce=&application/json&)
public @ResponseBody Something query(@RequestBody Something some,HttpServletRequest request, HttpServletResponse response){@PathVariable和@RequestParam的区别
请求路径上有个id的变量值,可以通过@PathVariable来获取 @RequestMapping(value = "/page/{id}", method = RequestMethod.GET) @RequestParam用来获得静态的URL请求入参
spring注解时action里用到。
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri
template中variable,不含queryString部分)的注解:
请求路径上有个id的变量值,可以通过@PathVariable来获取
@RequestMapping(value = "/page/{id}",
method = RequestMethod.GET)
@RequestParam用来获得静态的URL请求入参
spring注解时action里用到。
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri
template中variable,不含queryString部分)的注解:
B、处理request header部分的注解:
@RequestHeader,
C、处理request body部分的注解:@RequestParam,
D、处理attribute类型是注解: @SessionAttributes,
1、 @PathVariable
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过
@Pathvariable注解绑定它传过来的值到方法的参数上。
示例代码:
@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部分:
localhost:8080
text/html,application/xhtml+xml,application/q=0.9
Accept-Language
fr,en-q=0.7,q=0.3
Accept-Encoding
gzip,deflate
Accept-Charset
ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive
@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值:
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
参数绑定的代码:
@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用来指示参数是否必须绑定;
示例代码:
@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&里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageC
示例代码:
@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 对象;
示例代码:
@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的示例代码:
// 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示例代码:
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) {
@SessionAttributes有无绑定的Pet对象,若没有则查询@ModelAttribute方法层面上是否绑定了Pet对象,若没有则将URI
template中的值按对应的名称绑定到Pet对象的各属性上。
本文转自:苦逼的青春http://csjava./blog/static/8/?COLLCC=&COLLCC=&COLLCC=&
阅读(...) 评论()

我要回帖

更多关于 get 和post 的文章

 

随机推荐