问题
Trying to set up an application to display MongoDB nested data (two levels of nesting and embedding) in a web application (for business analysis).
I'm using Dropwizard, so I copied the dropwizard-mongo example, reduced it to the necessary parts (no delete, no insert, no metrics or anything).
App.java
package test;
import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import com.meltmedia.dropwizard.mongo.MongoBundle;
import test.Res;
public class App extends Application<Config> {
public static void main(String[] args) throws Exception {
new App().run(args);
}
MongoBundle<Config> mongoBundle;
@Override
public void initialize(Bootstrap<Config> bootstrap) {
bootstrap.addBundle(mongoBundle =
MongoBundle.<Config> builder()
.withConfiguration(Config::getMongo).build());
}
@Override
public void run(Config config, Environment env) throws Exception {
env.jersey().register(new Res(mongoBundle.getDB()));
}
}
Res.java (Resource class)
package test;
import java.util.List;
import java.util.Set;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mongodb.DB;
@Path("/")
public class Res {
DB database;
Jongo jongo;
public Res(DB database) {
this.database = database;
this.jongo = new Jongo(database);
}
@GET
@Produces("application/json")
public Set<String> collectionNames() {
return database.getCollectionNames();
}
@Path("{collectionName}")
public CollectionResource collection(@PathParam("collectionName") String name) {
return new CollectionResource(jongo.getCollection(name));
}
public class CollectionResource {
MongoCollection collection;
public CollectionResource(MongoCollection collection) {
this.collection = collection;
}
@GET
@Produces("application/json")
public List<String> list() {
return collection.distinct("_id").as(String.class);
}
@GET
@Path("{id}")
@Produces("application/json")
public ObjectNode getDocument(@PathParam("id") String id) {
ObjectNode node = collection.findOne("{_id: #}", id).as(ObjectNode.class);
if (node == null) {
throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
}
return node;
}
}
}
I can curl to / and will get the collections returned, so I'll say the connection to the DB works. However, if I curl any of the collections, be it the actual data or a dummy with just plain KVP of letters and numbers or even just an empty object (_id only), I always get
com.fasterxml.jackson.databind.JsonMappingException: org.bson.types.ObjectId cannot be cast to java.lang.String
Given I hardly did anything to the example, I'm somewhat at loss for ideas what to do about this.
回答1:
Do you have a POST method creating data or are you using an existing collection?
You can see here that in their example, they are are explicitly treating _id as a String and NOT an ObjectId. My guess is that was to get around the very issue you are seeing here.
Jongo has many ways of mapping an ObjectId, but they all requiring using a custom POJO and annotating the id field so they wont be as flexible as the example shown.
If possible, convert all your _id fields in the database to be plain strings, otherwise you will need to find someway to deal with the ObjectId type (either typing to to a POJO or modifying the Jongo Mapper perhaps).
Good Luck :)
来源:https://stackoverflow.com/questions/42300157/jackson-cant-deserialize-mongodb-object-passed-through-rest