操作系统:Windows Vista,框架:Jqgrid(最新),Spring(最新),JQuery(最新) 我正在使用Jqgrid将表单发布到Spring Controller以保持不变。当Spring控制器尝试将请求参数自动绑定到域对象时,它会在尝试绑定“Date”数据类型时抛出异常。我使用JSon格式传输数据。 Jqgrid正确显示日期。传输字符串包含'& -quot;'导致异常的日期之前和之后的字符。我不知道如何从Jqgrid中删除转义字符。我不知道在Spring有机会自动绑定之前如何拦截字符串。感谢您的帮助。
public class JsonDateSerializer extends JsonSerializer<Date> {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
AtOverride
public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
throws IOException, JsonProcessingException {
String formattedDate = dateFormat.format(date);
gen.writeString(formattedDate);
}
}
我的控制器类有initBinder方法。
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
Exception stack trace
nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "2010-12-01 11:10:00" from type 'java.lang.String' to type 'java.util.Date'; nested exception is java.lang.IllegalArgumentException]
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:820)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:359)
答案 0 :(得分:1)
如果我今天有空的话,我会尝试在我的博客上设置教程。
我的JSP文件只是一个简单的JSP文件,带有典型的JqGrid声明:
<script type="text/javascript">
jq(function() {
// This is the grid
jq("#grid").jqGrid({
url:'/myapp/users',
datatype: 'json',
mtype: 'GET',
colNames:['Id','Username','First Name'],
colModel:[
{name:'id',index:'id', width:55,editable:false,editoptions:{readonly:true,size:10},hidden:true},
{name:'firstName',index:'firstName', width:100,editable:true, editrules:{required:true}, editoptions:{size:10}, editrules:{required:true}},
{name:'lastName',index:'lastName', width:80, align:"right",editable:true, editrules:{required:true}, editoptions:{size:10}, editrules:{required:true}}
],
postData: {
// Here you can post extra parameters
// For example using JQuery you can retrieve values of other css elements
},
rowNum:10,
rowList:[10,20,30],
height: 200,
autowidth: true,
rownumbers: true,
pager: '#pager',
sortname: 'id',
viewrecords: true,
sortorder: "asc",
caption:"Users",
emptyrecords: "Empty records",
loadonce: false,
loadComplete: function() {
// Here you can provide extra functions after the grid is loaded completely
// Like auto-height function
},
jsonReader : {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
cell: "cell",
id: "id"
}
});
// This is the pager
jq("#grid").jqGrid('navGrid','#pager',
{edit:false,add:false,del:false,search:true},
{ },
{ },
{ },
{
sopt:['eq', 'ne', 'lt', 'gt', 'cn', 'bw', 'ew'],
closeOnEscape: true,
multipleSearch: true,
closeAfterSearch: true }
);
// Custom Add button on the pager
jq("#grid").navButtonAdd('#pager',
{ caption:"Add",
buttonicon:"ui-icon-plus",
onClickButton: addRow,
position: "last",
title:"",
cursor: "pointer"
}
);
// Custom Edit button on the pager
jq("#grid").navButtonAdd('#pager',
{ caption:"Edit",
buttonicon:"ui-icon-pencil",
onClickButton: editRow,
position: "last",
title:"",
cursor: "pointer"
}
);
// Custom Delete button on the pager
jq("#grid").navButtonAdd('#pager',
{ caption:"Delete",
buttonicon:"ui-icon-trash",
onClickButton: deleteRow,
position: "last",
title:"",
cursor: "pointer"
}
);
// Toolbar Search
jq("#grid").jqGrid('filterToolbar',{stringResult: true,searchOnEnter : true, defaultSearch:"cn"});
});
注意我在这里使用JQuery的noConflict方法。由于我有另一个使用 $ 的Javascript框架,我强迫JQuery为自己使用不同的标识符。我选择了jq,这是宣言:
<script type="text/javascript">
var jq = jQuery.noConflict();
</script>
上面的Javascript可以在JSP的head部分声明。 JqGrid声明的关键部分是 jsonReader 和数据类型。确保colModel名称与您的模型属性匹配。
答案 1 :(得分:0)
你可能会使用StringTrimmerEditor的第二个构造函数删除那些额外的字符
StringTrimmerEditor(String charsToDelete, boolean emptyAsNull)
基于Spring文档:
charsToDelete - 除了修剪输入字符串外,还要删除的一组字符。用于删除不需要的换行符。例如。 “\ r \ n \ f”将删除字符串中的所有新行和换行符。
我也使用最新版本的JqGrid和Spring 3,但我处理参数的方式似乎更简单。我是这样做的:
@Controller
@RequestMapping("/json")
public class JsonController {
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody JsonResponse getAll(
@RequestParam("_search") String search,
@RequestParam(value="filters", required=false) String filters,
@RequestParam(value="datefrom", required=false) String datefrom,
@RequestParam(value="dateto", required=false) String dateto,
@RequestParam(value="page", required=false) String page,
@RequestParam(value="rows", required=false) String rows,
@RequestParam(value="sidx", required=false) String sidx,
@RequestParam(value="sord", required=false) String sord
) { ... }
所有参数都以普通字符串形式传递。 datefrom 和 dateto 是我从JqGrid传递的自定义参数。日期来自JQuery的DatePicker,并通过JqGrid postData传递:
postData: {
datefrom: function() { return jq("#datepicker_from").datepicker("getDate"); },
dateto: function() { return jq("#datepicker_to").datepicker("getDate"); }
},
JsonResponse 是一个简单的POJO,我用它来映射JqGrid传递的搜索参数:
public class JsonResponse {
/**
* Current page of the query
*/
private String page;
/**
* Total pages for the query
*/
private String total;
/**
* Total number of records for the query
*/
private String records;
/**
* An array that contains the actual data
*/
private List<MyDTO> rows;
public JsonResponse() {
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getRecords() {
return records;
}
public void setRecords(String records) {
this.records = records;
}
public List<MyDTO> getRows() {
return rows;
}
public void setRows(List<MyDTO> rows) {
this.rows = rows;
}
}
MyDTO 也是一个简单的DTO对象。
在我的Spring applicationContext.xml中,我只需要声明以下内容:
<mvc:annotation-driven/>
并添加了Jackson jar用于从JSON转换为POJO,反之亦然
要将String日期转换为实际日期,我使用了很棒的Joda库。但是,当然,您可以使用JDK的标准日期。
答案 2 :(得分:0)
如果您注意到我的JSP,我添加了自定义按钮。 onClickButton 调用另一个Javascript函数。例如,在添加按钮上,我有addRow功能。这是函数声明:
function addRow() {
// Get the currently selected row
jq("#grid").jqGrid('editGridRow','new',
{ url: "/myapp/users/add",
editData: {
// Here you add extra post parameters
},
recreateForm: true,
beforeShowForm: function(form) {
// Here you can add, disable, hide elements from the popup form
},
closeAfterAdd: true,
reloadAfterSubmit:false,
afterSubmit : function(response, postdata)
{
// This is a callback function that will evaluate the response sent by your Controller
var result = eval('(' + response.responseText + ')');
var errors = "";
if (result.success == false) {
// Do whatever you like if not successful
} else {
// Do whatever you like if successful
}
// only used for adding new records
var new_id = null;
// Then this will be returned back to the popup form
return [result.success, errors, new_id];
}
});
}
记下网址:
url: "/myapp/users/add"
这是处理添加请求的控制器的映射
答案 3 :(得分:0)
现在,对于杰克逊序列化/反序列化,你会感到惊讶它是多么容易。
首先,确保您的类路径中有最新的Jackson库。接下来,打开Spring xml配置,并添加以下内容:
<mvc:annotation-driven/>
就是这样:))
确保您拥有最新的依赖关系jar。我使用Spring 3.0.4。已经有3.0.5了。另外,请确保您拥有最新的aspectjweaver.jar。如果您想知道mvc-annotation驱动标签内部的内容,只需搜索网络,您就会看到它包含的内容。基本上它会自动为JSON声明一个HTTPMessageConverter,并默认使用Jackson。
答案 4 :(得分:0)
对于Controller,这是到/ myapp / users / add请求的映射:
@Controller
@RequestMapping("/myapp/users")
public class UserController {
@RequestMapping(value = "/add", method = RequestMethod.POST)
public @ResponseBody JsonGenericResponse addAsJson(
@RequestParam("id") String id,
@RequestParam("firstName") String firstName,
@RequestParam("lastName") String lastName
) {
// Validate input
// Process data. Call a service, etc.
// Send back a response
// JsonGenericResponse is a custom POJO
// Jackson will automatically serialize/deserialize this POJO to a JSON
// The @ResponseBody annotation triggers this behavior
JsonGenericResponse response = new JsonGenericResponse();
response.setSuccess(false);
response.setMessage("Error in server");
return response;
}
}
这是JsonGenericResponse:
public class JsonGenericResponse {
private Boolean success;
private List<String> message;
public JsonGenericResponse() {
message = new ArrayList<String>();
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public List<String> getMessage() {
return message;
}
public void setMessage(String message) {
this.message.add(message);
}
}
这真的是一个简单的POJO。
在JSP中,要处理响应,请在JqGrid中使用JavaScript。响应将被发送回调用者(在这种情况下为添加表单)。以下是处理响应的示例JavaScript:
if (result.success == false) {
for (var i = 0; i < result.message.length; i++) {
errors += result.message[i] + "<br/>";
}
} else {
jq("#dialog").text('Entry has been edited successfully');
jq("#dialog").dialog(
{ title: 'Success',
modal: true,
buttons: {"Ok": function() {
jq(this).dialog("close");}
}
});
}
return [result.success, errors, null];