在Spring REST控制器中将JSON映射到Hibernate模型 [英] Mapping JSON to Hibernate models in Spring REST Controllers
问题描述
RestController
。创建一个获取记录的方法并不困难: @RequestMapping(value =/ stuff / list,method = RequestMethod .GET)
public List< Stuff> getStuff(){
return stuffService.findAll();
}
杰克逊处理对象序列化,没有问题。但是如果我想添加一个通过POST请求创建新记录的方法呢?有没有简单的方法来支持这样的简单方法?
@RequestMapping(value =/ stuff / new,method = RequestMethod.POST)
public Integer getStuff(@RequestParam(stuff)Stuff stuff){
return stuffService.save(stuff);
}
是这样的可能吗?或者我需要手动将发布的表单数据映射到新对象?
解决方案
以下是我解决问题的方法,脚步。首先,我的最终控制器方法:
@RequestMapping(value =/ stuff / new,method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
return stuffService.save(stuff);
}
我已经有一个过滤器应用于应用程序API的所有请求,跨源数据共享,但需要进行修改以允许请求指定内容类型: b
$ b @Override public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,
FilterChain filterChain)throws IOException,ServletException {
HttpServletResponse response =(HttpServletResponse)servletResponse;
response.setHeader(Access-Control-Allow-Origin,*);
response.setHeader(Access-Control-Allow-Methods,POST,GET,OPTIONS,DELETE);
response.setHeader(Access-Control-Max-Age,3600);
response.setHeader(Access-Control-Allow-Headers,x-requested-with,Content-Type);
filterChain.doFilter(servletRequest,servletResponse);
$ b @Override public void init(FilterConfig filterConfig)throws ServletException {}
$ b $ @Override public void destroy(){}
}
在我的 web.xml中注册
file:
< filter>
< filter-name> cors< / filter-name>
< filter-class> com.company.app.util.SimpleCORSFilter< / filter-class>
< / filter>
< filter-mapping>
< filter-name> cors< / filter-name>
< url-pattern> / api / *< / url-pattern>
< / filter-mapping>
现在,当我提出请求时,例如下面的请求,它会正确地将我提交的JSON映射到我的模型,并坚持一个新的实例:
$ $ p $ var stuff = {
name:Some stuff,
描述:这是一些东西。
$ .ajax({
url:url,
method:post,
dataType:json,
data:JSON.stringify(stuff),
contentType:application / json
})。done(function(data){
console.log(data);
} ).fail(function(x,status,e){
console.log(e);
});
为了告诉Spring你想让它应用一个解串器到内容而不是尝试标准的HTML表单绑定你使用 @RequestBody
。
<$ c $ (@RequestBody的东西){
返回stuffService.save(东西); / /。
}
@RequestParam
是告诉它查找具有该名称的单个参数并应用标准数据绑定,而不是将POST的全部内容反序列化到对象中。
Let's say that I have a Spring 4 web application with a Hibernate-based persistence layer. I'd like to create a RestController
that supports basic CRUD operations for my models. Creating a method for fetching records works without a hitch:
@RequestMapping(value = "/stuff/list", method = RequestMethod.GET)
public List<Stuff> getStuff(){
return stuffService.findAll();
}
Jackson handles the object serialization, no problem. But what if I want to add a method for creating new records via a POST request? Is there any easy way to support a simple method like this?
@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestParam("stuff") Stuff stuff){
return stuffService.save(stuff);
}
Is something like this possible? Or do I need to manually map posted form data to a new object?
SOLUTION
Here is how I solved my problem, there were a couple steps. First, my final controller method:
@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
return stuffService.save(stuff);
}
I already had a filter applied to all requests to the application API, to allow cross origin resource sharing, but modifications to this were needed to allow requests to specify content type:
public class SimpleCORSFilter implements Filter{
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void destroy() { }
}
Which is registered in my web.xml
file:
<filter>
<filter-name>cors</filter-name>
<filter-class>com.company.app.util.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
Now when I make a request, such as the one below, it will correctly map my submitted JSON to my model and persist a new instance:
var stuff = {
name: "Some stuff",
description: "This is some stuff."
}
$.ajax({
url: url,
method: "post",
dataType: "json",
data: JSON.stringify(stuff),
contentType: "application/json"
}).done(function(data){
console.log(data);
}).fail(function(x, status, e){
console.log(e);
});
To tell Spring that you want it to apply a deserializer to the content instead of attempt standard HTML form binding you use @RequestBody
.
@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
return stuffService.save(stuff);
}
@RequestParam
is telling it to look for an individual parameter with that name and apply standard databinding, not to deserialize the entire content of the POST into an object.
这篇关于在Spring REST控制器中将JSON映射到Hibernate模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!