Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在SpringREST控制器中将JSON映射到Hibernate模型_Java_Json_Hibernate_Rest_Spring Mvc - Fatal编程技术网

Java 在SpringREST控制器中将JSON映射到Hibernate模型

Java 在SpringREST控制器中将JSON映射到Hibernate模型,java,json,hibernate,rest,spring-mvc,Java,Json,Hibernate,Rest,Spring Mvc,假设我有一个Spring4Web应用程序,它有一个基于Hibernate的持久层。我想创建一个RestController,它支持我的模型的基本CRUD操作。创建一种获取记录的方法不会有任何问题: @RequestMapping(value = "/stuff/list", method = RequestMethod.GET) public List<Stuff> getStuff(){ return stuffService.findAll(); } 这样的事情可能吗?

假设我有一个Spring4Web应用程序,它有一个基于Hibernate的持久层。我想创建一个
RestController
,它支持我的模型的基本CRUD操作。创建一种获取记录的方法不会有任何问题:

@RequestMapping(value = "/stuff/list", method = RequestMethod.GET)
public List<Stuff> getStuff(){
    return stuffService.findAll();
}
这样的事情可能吗?还是需要手动将已发布的表单数据映射到新对象

解决方案

下面是我解决问题的方法,有几个步骤。首先,我的最终控制器方法:

@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
    return stuffService.save(stuff);
}
我已经对应用程序API的所有请求应用了一个过滤器,以允许跨源资源共享,但需要对此进行修改,以允许请求指定内容类型:

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() { }
}
已在我的
web.xml
文件中注册:

<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>

是的,绝对是。Jackson将自动对实体进行双向映射,因此,如果您想
向服务器发布
内容,只需使用与执行
GET
时相同的JSON格式,告诉Spring您希望它对内容应用反序列化程序,而不是尝试使用
@RequestBody
的标准HTML表单绑定

@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
    return stuffService.save(stuff);
}

@RequestParam
告诉它查找具有该名称的单个参数并应用标准数据绑定,而不是将POST的整个内容反序列化为对象。

内容是html表单POST还是JSON?@Affe:JSON,通过浏览器AJAX请求或通过Spring
RestTemplate
发送。是否需要显式设置
consumes=“application/something”
?或者它希望使用正确的JSON格式?是否需要任何其他请求标头?仅当您希望将具有不同标头的请求路由到不同的位置或将其锁定时。对于简单的事情,开箱即用的
将“正确处理”。(注意,如果您指定使用,则具有有效内容但缺少标题的请求将被拒绝,您可能希望也可能不希望如此。)像这样编写我的控制器方法将导致
415(不支持的媒体类型)
错误。另一个SO答案()建议更改请求头,但这也没有帮助。您是使用mvc:annotation-driven配置调度器还是手动设置它?Jackson在类路径上吗?我使用了
,但做了修改(见上文)。Jackson在类路径上,可以很好地进行对象序列化。
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);
  });
@RequestMapping(value = "/stuff/new", method = RequestMethod.POST)
public Integer getStuff(@RequestBody Stuff stuff){
    return stuffService.save(stuff);
}