问题:
我正在尝试将value
的请求发送到参数:select
并收到此错误(415不支持的媒体类型)。
框架:
Spring 4.1.1
在服务器端的POST
中,我有以下内容:
{id: 20, roleName: "ADMIN"}
这 - > @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
答案 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
批注。它对我有用