415不支持的媒体类型+弹簧

时间:2015-06-30 14:39:49

标签: java spring jackson

问题:
我正在尝试将value的请求发送到参数:select并收到此错误(415不支持的媒体类型)。

框架:
Spring 4.1.1

在服务器端的POST中,我有以下内容:

{id: 20, roleName: "ADMIN"}

这 - &gt; @Controller适用于任何其他类型的对象,但对于@RequestMapping("/role/add.action") @ResponseBody public Map<String,Object> addrole(@RequestBody Role role, HttpServletRequest request, Authentication authentication, HttpServletResponse response) { //Code goes here.. } ,我会遇到此问题。

我的@RequestBody Role role课程是:

Role

此类具有Role个属性,我认为这可能会导致问题。

我只发送两个属性:id和roleName。演员应该工作,对吗?

PS:我已经设置了一个杰克逊@Entity public class Role implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id private int id; @Column private String roleName; @Fetch(FetchMode.SELECT) @OneToMany(mappedBy = "role", targetEntity = Users.class, fetch = FetchType.EAGER) @JsonManagedReference(value="role") private List<Users> users = new LinkedList<Users>(); @Fetch(FetchMode.SELECT) @ManyToMany(fetch=FetchType.EAGER) @JoinTable(name="role_features", joinColumns=@JoinColumn(name="roleId"), inverseJoinColumns=@JoinColumn(name="featureId")) @OrderBy(clause="featureId") private Set<SystemFeature> features = new HashSet<SystemFeature>(); @Fetch(FetchMode.SELECT) @ManyToMany(fetch=FetchType.EAGER) @JoinTable(name="role_menu", joinColumns=@JoinColumn(name="roleId"), inverseJoinColumns=@JoinColumn(name="menuId")) @OrderBy(clause="menuId") private Set<Menu> menus = new HashSet<Menu>(); @Fetch(FetchMode.SELECT) @ManyToMany(fetch=FetchType.EAGER) @JoinTable(name="role_services_stations", joinColumns=@JoinColumn(name="roleId"), inverseJoinColumns=@JoinColumn(name="stationId")) @OrderBy(clause="stationId") private Set<ServiceStation> stations = new HashSet<ServiceStation>(); //Constructors, getters and setters... } bean,但没有用。

java.util.Set

有人可以帮助我吗?的xD

3 个答案:

答案 0 :(得分:2)

我的问题基本上是@JsonManagedReference注释。

我做了什么:

1)我将有效负载更改为Map

public Map<String,Object> addRole(@RequestBody Map payload, 
            HttpServletRequest request,
            Authentication authentication,
            HttpServletResponse response) {
...
}

2)然后我尝试用杰克逊的ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)投射它:

ObjectMapper mapper = new ObjectMapper();

Role role = mapper.convertValue(payload, Role.class);

然后调试器给我一个例外:

java.lang.IllegalArgumentException: Can not handle managed/back reference 'parent': no back reference property found from type [collection type; class java.util.Set, contains [simple type, class br.com.ttrans.samapp.model.Menu]]

此异常有助于发现问题,(在我的情况下)是注释@JsonManagedReference。来自docs

  

用于表示带注释的属性是字段之间双向链接的一部分的注释;并且它的作用是&#34;父母&#34; (或&#34;转发&#34;)链接。属性的值类型(类)必须具有使用JsonBackReference注释的单个兼容属性。处理链接使得用这个注释注释的属性得到正常处理(正常序列化,反序列化没有特殊处理);它是匹配的后向引用,需要特殊处理

这用于双向链接,我的有效负载来自单向。所以..

3)...我删除了@JsonManagedReference个注释,并且只在所有嵌套类中保留@JsonBackReference;

然后debbuger再次向我抛出异常,但这次是java.lang.IllegalArgumentException: Unrecognized field ...所以把@JsonIgnoreProperties(ignoreUnknown = true)放在所有类上解决了我的问题。

因此,毕竟我可以收到已经解析为Role的有效负载:

@RequestMapping("/role/add.action")
@ResponseBody
public Map<String,Object> addRole(@RequestBody Role role, 
            HttpServletRequest request,
            Authentication authentication,
            HttpServletResponse response) {

            ...
}

希望它有所帮助!

答案 1 :(得分:0)

这显然是由于ManyToMany关联(如功能,菜单等)。 修改它会打破json链,可能会在合适的地方添加@JsonIgnore来解决它。

答案 2 :(得分:0)

不要同时使用@JsonBackReference@JsonManagedReference。仅删除@JsonManagedReference批注。它对我有用