我正在制作一个restful应用程序,并尝试将对象列表转换为特定url(@RequestMapping/@ResponseBody)的json
我的类路径中有jackson-hibernate4和jackson-core,datind等。
这是我想用json转换的对象。
@Entity
@Table(name="Product")
public class Product {
@Id
@Column(name="productId")
@GeneratedValue
protected int productId;
@Column(name="Product_Name")
protected String name;
@Column(name="price")
protected BigDecimal baseprice;
@OneToMany(cascade = javax.persistence.CascadeType.ALL,mappedBy="product",fetch=FetchType.EAGER)
protected List<ProductOption> productoption = new ArrayList<ProductOption>();
@OneToMany(cascade = javax.persistence.CascadeType.ALL,mappedBy="product",fetch=FetchType.EAGER)
protected List<ProductSubOption> productSubOption = new ArrayList<ProductSubOption>();
@ManyToOne
@JoinColumn(name="ofVendor")
protected Vendor vendor;
产品中的两个对象也是POJO的...
下面是我检索产品列表的方法
@Override
public List<Product> getMenuForVendor(int vendorId) {
List<Product> result = em.createQuery("from "+Product.class.getName()+" where ofVendor = :vendorId").setParameter("vendorId", vendorId).getResultList();
System.out.println(result.size());
return result;
}
当我试图在我的控制器中返回这个列表时,我得到了一个“不能为json延迟加载”,所以我设置了我的对象以急切地获取。这是我的控制器
@Autowired
private MenuDaoImpl ms;
@RequestMapping(value = "/{vendorId}", method = RequestMethod.GET)
public @ResponseBody List<Product> getMenu(@PathVariable int vendorId){
List<Product> Menu = html" target="_blank">Collections.unmodifiableList(ms.getMenuForVendor(vendorId));
return Menu;
}
现在,当我点击我的url localhost:8080/getMenu/1时,我应该会看到一个json字符串,但我会看到一大堆错误
WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Handling of [org.springframework.http.converter.HttpMessageNotWritableException] resulted in Exception
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:467)
Could not write JSON: Infinite recursion (StackOverflowError) (through reference chain:
我不确定我是否遗漏了什么。请导游。
我意识到这可能不是你所追求的100%,但从来没有少过,我想分享它,因为我花了很多时间来解决这个问题。
此外,您可以考虑自定义Json解析器,而不是使用Json注释。确保为Jackson jar使用正确的包,因为它们最近更改了它们的包结构(当您使用它们的任何带有数字2的类时,如下面所示)。
首先创建一个HttpMessageConzer:
@Bean
public HttpMessageConverter jacksonMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setPrefixJson(false);
converter.setPrettyPrint(true);
converter.setObjectMapper(objectMapper());
return converter;
}
添加ObjectMapper,在其中附加映射模块并附加将使用的序列化程序。
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
SimpleModule module = new SimpleModule("jacksonJsonMapper", Version.unknownVersion());
module.addSerializer(Product.class, new Product());
objectMapper.registerModule(module);
return objectMapper;
}
现在创建一个序列化程序。这个类将提供您在获取对象时看到的输出,Jackson将完成其余的工作。您只需提供其外观的框架。
public class Product erializer extends JsonSerializer<Product> {
@Override
public void serialize(Product product, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if(product == null) {
//Handle it, if you want
}
if(product != null) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("id", productId.getId().toString());
jsonGenerator.writeStringField("title", product.getName());
jsonGenerator.writeStringField("basePrice", product.getBasePrice());
//Add items to the json array representation
jsonGenerator.writeArrayFieldStart("productoptions");
for(ProductOption productOption: product.getProductoption()) {
jsonGenerator.writeStartObject("field", productOption.getFoo());
jsonGenerator.writeEndObject();
}
jsonGenerator.writeEndArray();
jsonGenerator.writeEndObject();
}
}
}
另一方面,我仍然希望这一点会有用:在惰性地获取实体时,需要确保有一个可用的事务。您还应该记住,lazy是加载实体的首选方式,除非您每次获取任何引用时都想彻底摧毁服务器。
尝试通过在方法上添加@Transactional来更改获取数据的方法,以确保该方法在运行时有一个打开的事务,如果没有,则可能在尝试获取子对象时关闭该事务。
这个问题已经回答了。我只是简单地把一个好例子的链接,清楚地解释了问题和解决方案。http://geekabyte.blogspot.in/2013/09/fixing-converterhttpmessagenotwritablee.html
我使用@JsonBackReference对@manytone绑定和@JsonManagedReference对@OneToMany绑定进行了解决。
谢谢“Sotirios Delimanolis”
我想将Jackson2与<code>SpringRoboSpice commons-io-1.3.2.jar commons-lang3-3.2.1.jar jackson-annotations-2.2.3.jar jackson-core-2.2.3.jar jackson-databind-2.2.3.jar robospice-1.4.11.jar robospice-cache-1.4.
我正在使用spring(4.2.0.RELEASE)、hibernate validator(5.2.1.Final)和validation api(1.1.0.Final)对后端应用程序进行JSR验证,配置如下:, 但是没有一个JSR303注释在我的应用程序中工作。 注意:在POJO类上添加了JSR303注释,在服务类(使用POJO)上添加了@Validated注释,还尝试在方法级别添加@Val
我在pom.xml中使用的依赖关系: 我的用户POJO: 我的web服务:
我一直试图获得一个简单的web操作来向API发出一个经过身份验证的get请求(我已经从示例代码中删除了实际的url和秘密)。 我已经在本地成功地运行了这一点,但是当我测试web动作时,它只是在记录“调用Axios”之后死亡。 它不会报告错误,我尝试实现一个承诺,认为线程在api响应之前就结束了,但没有效果。有什么线索吗?
问题内容: 我想使用Android Studio使用Gradle构建工具开发应用程序。我无法在上插入存储库和库。我的文件如下: 如何在项目中添加OpenCV? 问题答案: 您可以在Android Studio中轻松完成此操作。 请按照以下步骤将Open CV作为库添加到您的项目中。 libraries在项目主目录下创建一个文件夹。例如,如果您的项目是OpenCVExamples,则将创建一个Ope
我想使用Android Studio开发一个应用程序使用Gradle构建工具。我无法在上插入OpenCV repo和库。我的文件如下所示: 我如何在我的项目中添加OpenCV?