java


Overcome “Can not construct instance of InterfaceClass” without hinting the parent


I have this method in my controller:
#RequestMapping(method = RequestMethod.POST)
InterfaceClass insert(#RequestBody InterfaceClass interfaceClass) {
// Do something
}
The error I am getting is pretty straightforward and self-explanatory:
Can not construct instance of InterfaceClass: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information.
Basically, I need to tell Spring that I have a concrete implementation of InterfaceClass, ClassImpl.
I tried:
#JsonRootName("InterfaceClass")
public class ClassImpl implements InterfaceClass {
}
to no extent. I cannot use #JsonTypeInfo as the parent interface class InterfaceClass should not be aware of ClassImpl and they are in different modules. What I have also tried:
Implement InterfaceClass with abstract AbstractClass and put:
#JsonDeserialize(as = AbstractClass.class)
on top of InterfaceClass. Then extend AbstractClass with ClassImpl. The error simply becomes:
Can not construct instance of InterfaceClass: abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information.
Further tried:
public class ControllerClass<E extends InterfaceClass> {
#RequestMapping(method = RequestMethod.POST)
InterfaceClass insert(#RequestBody E interfaceClass) {
InterfaceClass object = (InterfaceClass) interfaceClass;
}
}
and this results in:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to InterfaceClass
as expected.
I was really expecting Spring Boot to handle component discovery since there is only one concrete implementation of InterfaceClass or AbstractClass, which is ClassImpl in my classpath. Maybe I am doing something wrong? How can I overcome this, without explicitly hinting the InterfaceClass on where its implementation is (e.g. no #JsonDeserialize, etc.)?
Solution 1 - Dynamically register subtypes
You can define the subtypes dynamically.
1. On the interface, define a JSON field (#type) to be used as identifier:
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY, property = "#type")
public interface InterfaceClass {
}
2. Add "#type" field to your JSON payload
{
...
"#type": "someName"
}
2. Register the inteface's subtypes dynamically:
#Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder() {
public void configure(ObjectMapper objectMapper) {
objectMapper.registerSubtypes(ClassImpl.class);
super.configure(objectMapper);
};
};
return builder;
}
4. Specify the "#type" name on your concrete class (optional):
//Optional, otherwise uses the Simple class name (ie: 'ClassImpl')
#JsonTypeName("someName")
public class ClassImpl implements InterfaceClass {
}
5. Use can now use the interface with #RequestBody:
#RequestMapping(method = RequestMethod.POST)
InterfaceClass insert(#RequestBody InterfaceClass interfaceClass) {
}
Solution 2 - Dynamically register a custom Deserializer
If adding a #type field isn't possible (or not wanted), you may also define a Custom Deserializer for your interface, which would in fact create a ClassImpl:
1. Define a custom deserializer:
class ClassImplJsonDeserializer extends JsonDeserializer<ClassImpl> {
#Override
public ClassImpl deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return jp.readValuesAs(ClassImpl.class).next();
}
}
2. Dynamically set the custom deserializer:
#Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.deserializerByType(InterfaceClass.class, new ClassImplJsonDeserializer());
return builder;
}
3. Remove #JsonTypeInfo from the interface:
public interface InterfaceClass {
}

Related Links

For loop how to print to console without leaving on first iteration java
Dispatcher servlet throws exception: NumberFormatException
Overriding equals method to accept doubles inside of Object class. Java
Line break between GWT widgets
How to set shift in String.format dynamically? [duplicate]
Java audio doesn't play in jar file
How can I obtain the -D parameters passed in to Java launch
Set multiple listeners to one method
why one class of same package can't access another?
cannot find symbol : class NumberTools
Java apache POI java.lang.IllegalArgumentException: Position 21504 past the end of the file
Selenium Automatically Closes Chrome Console (attached or window)
How to check values in collection for uniques by some criteria using Java 8
java.util.concurrent.locks.Condition awaitUninterruptibly()
what is the purpose of this tmp variable in android sample bluetooth chat application
ASM. Clone JumpInsnNode correctly

Categories

HOME
date
listview
keras
angular-material
mean-stack
baqend
ezpublish
azure-media-services
django-imagekit
adfs
applepay
windows-10-universal
vault
fancybox-3
google-apps-marketplace
usergrid
remote-access
phaser
foselasticabundle
pc
facebook-page
apache-metamodel
undefined
karma-jasmine
introduction
kryo
object-detection
java-3d
numerical-methods
spark-jobserver
chromebook
virtualdub
tooltipster
windows-error-reporting
opentype
procdump
instant-messaging
microsoft-chart-controls
bosh
galsim
http-status-code-503
oracle-fusion-middleware
noraui
typed.js
pim
hybridauth
rotational-matrices
plsql-psp
lto
occlusion
starteam
objectlistview
service-discovery
document.write
mapzen
gulp-sourcemaps
dynamic-reports
quadratic-programming
glew
botbuilder
mime
bootstrap-dialog
total-commander
.net-4.6.2
apple-news
errordocument
dandelion
magma
ifs
zendesk-app
setuptools
bonobo
ado.net-entity-data-model
adxstudio-portals
ctest
xml-attribute
storekit
gstreamer-0.10
wapiti
uid
t4mvc
simple-framework
pundit
ibaction
method-parameters
ami
system32
device-orientation
truevault
npapi
dia
java.util.concurrent
asp.net-web-api-odata
internet-connection
has-many-through
jubula
blending
spring-validator
sharp-repository
kyotocabinet
tinn-r
mhtml
isnullorempty
jspinclude
ocx
regsvr32
buildr
deobfuscation
joyent
table-footer
telerik-scheduler
visitor-statistic
getresponsestream
thunderbird-lightning
swing-app-framework
sector
misv

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App