从 EXTJS 存储发送的 JSON 文件中反序列化多个任务(数据)时遇到问题。在更新单个任务时,其工作正确。但是当我们更新多个任务时,它会显示
org.codehaus.jackson.map.JsonMappingException:无法反序列化 bryntum.com.gnt.model.Task 的实例START_ARRAY令牌
我正在使用Spring MVC和Hibernate。我的 Web 控制器代码是。
package bryntum.com.gnt.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.json.*;
import bryntum.com.gnt.model.Task;
import bryntum.com.gnt.model.TaskWrapper;
import bryntum.com.gnt.service.TaskService;
import bryntum.com.gnt.util.ReturnTasks;
@Controller
public class TaskController {
private TaskService taskService;
@RequestMapping(value="/tasks/update.action")
public @ResponseBody String update (@RequestBody TaskWrapper data) throws Exception {
try{
TaskWrapper tw=(TaskWrapper)data;
List<Task> tasks = taskService.update(tw.getData());
return ReturnTasks.mapOK(tasks);
} catch (Exception e) {
return ReturnTasks.mapError("Error trying to update task. ");
}
}
@Autowired
public void setEventService(TaskService taskService) {
this.taskService = taskService;
}
}
服务类代码是..
package bryntum.com.gnt.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import bryntum.com.gnt.dao.TaskDAO;
import bryntum.com.gnt.model.Task;
@Service
public class TaskService {
private TaskDAO taskDAO;
@Transactional
public List<Task> update(Task record){
List<Task> returnTasks = new ArrayList<Task>();
returnTasks.add(taskDAO.saveTask(record));
return returnTasks;
}
@Autowired
public void setTaskDAO(TaskDAO taskDAO) {
this.taskDAO = taskDAO;
}
}
用于处理 JSON 的 Util 类代码。
package bryntum.com.gnt.util;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.*;
import bryntum.com.gnt.model.Task;
import org.codehaus.jackson.map.DeserializationConfig;
@Component
public class ReturnTasks {
private static JSONObject sortedByParentTasks = null;
private static JSONArray tasksTree = null;
private static JSONObject taskChildrenObject;
/**
* Generates JSON String to return in the modelAndView
* @param tasks
* @return
* @throws JSONException
* @throws IOException
* @throws JsonMappingException
* @throws JsonGenerationException
*/
public static String mapOK(List<Task> tasks) throws JSONException, JsonGenerationException, JsonMappingException, IOException{
tasksTree = null;
tasksTree = new JSONArray();
sortedByParentTasks = null;
sortedByParentTasks = new JSONObject();
tasksTree = makeTree(tasks);
return tasksTree.toString();
}
private static JSONArray makeTree(List<Task> list) throws JSONException, JsonGenerationException, JsonMappingException, IOException{
ObjectMapper om= new ObjectMapper();
Iterator<Task> listIterator = list.iterator();
String parentId;
while(listIterator.hasNext()){
om=om.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
om.enable(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
Task task = listIterator.next();
JSONArray equalParentId;
parentId = ""+task.getParentId();
String json = om.writeValueAsString(task);
JSONObject taskJSON = new JSONObject(json);
if (sortedByParentTasks.has(parentId)){
sortedByParentTasks.accumulate(parentId, taskJSON);
} else {
equalParentId = new JSONArray();
equalParentId.put(taskJSON);
sortedByParentTasks.put(parentId, equalParentId);
}
}
addNodes(sortedByParentTasks.getJSONArray("null"));
return tasksTree;
}
private static void addNodes(JSONArray nodes) throws JSONException{
for(int i=0, l=nodes.length(); i<l; i++){
taskChildrenObject = nodes.getJSONObject(i);
listHierarchy(taskChildrenObject);
tasksTree.put(taskChildrenObject);
}
}
private static void listHierarchy(JSONObject task) throws JSONException{
JSONArray childrenArray = new JSONArray();
JSONArray childNodes = new JSONArray();
try {
childNodes = sortedByParentTasks.getJSONArray(""+task.get("Id"));
}catch(JSONException e){}
if (childNodes.length() > 0){
for (int i=0, l=childNodes.length(); i<l; i++) {
JSONObject childObject = childNodes.getJSONObject(i);
childrenArray.put(childObject);
try{
task.put("children", childrenArray);
task.put("leaf", false);
}catch(JSONException e){}
listHierarchy(childObject);
}
}
}
/**
* Generates modelMap to return in the modelAndView in case
* of exception
* @param msg message
* @return
*/
public static String mapError(String msg){
Map<String,Object> modelMap = new HashMap<String,Object>(2);
modelMap.put("message", msg);
modelMap.put("success", false);
return modelMap.toString();
}
}
模型类代码..
package bryntum.com.gnt.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonAutoDetect
@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
@Table(name="events")
public class Task implements Serializable {
@Id
@GeneratedValue
@Column(name="Id")
private int id;
@Column(name="Name", nullable=false)
private String name;
/*@Column(name="TASK", nullable=false)
private String task;
*/
@Column(name="StartDate", nullable=false)
private String startDate;
@Column(name="EndDate", nullable=false)
private String endDate;
@Column(name="parentId", nullable=true)
private Integer parentId;
/*
and more fields
*/
@JsonProperty("Id")
public int getId() {
return id;
}
@JsonProperty("Id")
public void setId(int id) {
this.id = id;
}
@JsonProperty("Name")
public String getName() {
return name;
}
@JsonProperty("Name")
public void setName(String name) {
this.name = name;
}
@JsonProperty("StartDate")
public String getStartDate() {
return startDate;
}
@JsonProperty("StartDate")
public void setStartDate(String start) {
this.startDate = start;
}
@JsonProperty("EndDate")
public String getEndDate() {
return endDate;
}
@JsonProperty("EndDate")
public void setEndDate(String end) {
this.endDate = end;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer id) {
this.parentId = id;
}
}
和用于任务的包装器克拉斯
package bryntum.com.gnt.model;
import java.io.Serializable;
public class TaskWrapper implements Serializable{
private Task data;
public Task getData() {
return data;
}
public void setData(Task data) {
this.data = data;
}
}
在控制器中,如果要更新多个对象,则应将方法更改为使用List作为参数:
公共@ResponseBody字符串更新(@RequestBody列表<任务包装器>任务)引发异常任务包装器>
这也取决于您如何使用批处理操作将 extjs 代理配置为 true 或 true。查看文档:http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.data.proxy.Proxy-cfg-batchActions