【问题标题】:415 unsupported media type + spring415 不支持的媒体类型 + 弹簧
【发布时间】:2015-09-17 10:20:57
【问题描述】:

问题:
我正在尝试以 POST 的形式发送请求,参数为:{id: 20, roleName: "ADMIN"} 并收到此错误(415 不受支持的媒体类型)。

框架:
春季4.1.1

在我的服务器端@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 班级是:

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

}

这个类有java.util.Set属性,我认为这可能会导致问题。

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

PS:我已经设置了一个 Jackson message-converter bean,但是没有用。

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean
                class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="serializationInclusion">
                            <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

有人可以帮助我吗? xD

【问题讨论】:

  • 你试过{"id": 20, "roleName": "ADMIN"}吗? (属性名称中的双引号)。还可以尝试将Content-Type 标头设置为application/json
  • 换成@RequestMapping(value="/role/add.action", consumes = "application/json")怎么办
  • @orid 有效负载已正确发送,并且在开发者工具上的 Content-Type 是 'Content-Type:application/json'。 =/
  • @Magnamag 我做了你说的改变,但也没有用..
  • 好的,你的控制器是返回null还是一个空值?

标签: java spring jackson


【解决方案1】:

这显然是由于多对多关联(如功能、菜单等)。 修改一下,打断json链,可能在合适的地方加上@JsonIgnore就可以解决了。

【讨论】:

  • 嗨 Charybr,我也这样做了,但没用...我发现这篇文章 stackoverflow.com/questions/19894955/… 作为解决方案,这个人从 fastxml 更改为 codehaus,但也没有用 =//
  • 我建议首先为所有 OneToMany、ManyToMany 关联添加 JsonIgnore 注释。然后一次删除一个关联的@JsonIgnore。通过这种方式,您将能够确定是哪个关联导致了这种情况。
【解决方案2】:

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

我做了什么:

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

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

2) 然后我尝试使用 Jackson 的 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

Annotation 用来表示被注解的属性是字段之间双向链接的一部分;并且它的作用是“父”(或“转发”)链接。属性的值类型(类)必须有一个使用 JsonBackReference 注释的兼容属性。链接被处理,使得被这个注解注解的属性被正常处理(正常序列化,反序列化没有特殊处理);需要特殊处理的是匹配的反向引用

这用于双向链接,我的有效载荷是单向。所以..

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

然后调试器向我抛出了另一个异常,但这次是: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) {

            ...
}

希望对你有帮助!

【讨论】:

  • 我遇到了几乎相同的问题,@JsonBackReference 的字段导致了错误。我用@JsonIgnore 替换了它,它解决了这个问题。感谢您的解释!
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2014-05-10
    • 2019-05-01
    • 2022-01-15
    • 2017-06-30
    • 2017-07-05
    • 2016-11-26
    • 2015-08-21
    相关资源
    最近更新 更多