我有一个Spring mvc @RestController类,其中method参数使用@RequestBody注释。像这样:
@RestController
@RequestMapping("/features")
public class FeatureController {
@PostMapping
public Feature createFeature(@RequestBody Feature feature) {
......
}
}
我的Feature
类有一个使用Builder
模式构建的私有构造函数。因此,我创建了名为HttpMessageConverter
的{{1}},并使用FeatureConverter
正确注册了它。转换器使用Jackson解析JSON,然后使用extendMessageConverters
创建Feature.Builder
的实例。
我的问题是Spring在我的自定义Feature
之前注册了MappingJackson2HttpMessageConverter
的实例。因此,即使在FeatureConverter
之前,MappingJackson2HttpMessageConverter
也会尝试进行解析。由于构造函数是私有的,因此FeatureConverter
失败。
我的问题是如何更改订单,以便在MappingJackson2HttpMessageConverter
之前询问FeatureConverter
。有没有正确的方法呢?
答案 0 :(得分:1)
Spring MVC WebMvcConfigurerAdapter
初始化HttpMessageConverters:
protected final List<HttpMessageConverter<?>> getMessageConverters() {
if (this.messageConverters == null) {
this.messageConverters = new ArrayList<HttpMessageConverter<?>>();
configureMessageConverters(this.messageConverters);
if (this.messageConverters.isEmpty()) {
addDefaultHttpMessageConverters(this.messageConverters);
}
extendMessageConverters(this.messageConverters);
}
return this.messageConverters;
}
请参阅:Github - WebMvcConfigurationSupport
如您所见,有3种方法:
configureMessageConverters
,默认情况下为空,您可以在此处添加转换器addDefaultHttpMessageConverters
,如名称所示,将创建所有默认转换器,在此处创建默认MappingJackson2HttpMessageConverter
。extendMessageConverters
作为文档:重写此方法以扩展或修改转换器列表 它已配置。例如,这可能是有用的 要注册的默认转换器然后插入自定义 转换器通过这种方法。
在添加了所有默认转换器后想要修改列表时使用。
要回答您的问题,如果您不需要默认转换器,则只需覆盖configureMessageConverters
并添加它:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FeatureConverter());
}
如果您需要它们,您可以复制粘贴addDefaultHttpMessageConverters
内容并将其添加到configureMessageConverters
并按照初始化顺序播放(丑陋的解决方案)。
否则,您可以使用extendMessageConverters
在默认初始化后添加它并使用命令:
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(the_index_you_want, new FeatureConverter());
}
答案 1 :(得分:0)
如果我理解正确,您希望使用# for specific class
-keepclassmembers class FQNClassName {
protected <fields>;
}
# for all classes
-keepclassmembers class * {
protected <fields>;
}
# other approach for default acl
# be careful as method could have also native modifiers :)
-keepclassmembers class * {
!public !protected !private *;
}
对Builder
对象进行反序列化。
也许你可以使用杰克逊注释(没有Feature
):
FeatureConverter
如果您使用import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
@JsonDeserialize(builder = Feature.FeatureBuilder.class)
public class Feature {
private final String name;
public Feature(String name) {
this.name = name;
}
public String getName() {
return name;
}
/**
* Builder
*/
@JsonPOJOBuilder(withPrefix = "")
public static final class FeatureBuilder {
private String name = "";
private FeatureBuilder() {
}
public static FeatureBuilder create() {
return new FeatureBuilder();
}
public FeatureBuilder name(String name) {
this.name = name;
return this;
}
/**
* Build Feature object
*/
public Feature build() {
Feature feature = new Feature(this.name);
return feature;
}
}
}
:
Lombok