在Spring REST控制器中将JSON映射到Hibernate模型 [英] Mapping JSON to Hibernate models in Spring REST Controllers

查看:118
本文介绍了在Spring REST控制器中将JSON映射到Hibernate模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个Spring 4 Web应用程序和一个基于Hibernate的持久层。我想创建一个支持我的模型的基本CRUD操作的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆