Java 8 Spring 4.3
我正在尝试在我的Web应用程序中实现Spring 4 MVC表单验证,但遇到了一些障碍,即 我似乎无法验证UPDATE。许多提示显示如何将验证应用于新对象然后保存(插入)。A
应用程序崩溃,并显示500“ bean名称'ruleDeckForm'的绑定结果和普通目标对象均不可用作请求属性” errmsg 如果
@ModelAttribute("ruleDeckForm")
public RuleDeckForm getRuleDeckForm() {
return new RuleDeckForm();
}
在BaseController中不存在。但这似乎使来自ajax调用的值无效。 更奇怪的行为是,使用@Valid时,RuleDeckFormValidator.validate中没有出现日志记录消息,但似乎默默执行,因为 控制器方法中的行报告发现了1个错误,这是我期望RuleDeckForm对象将所有空值显示的错误。删除@Valid 并手动调用验证程序执行但没有发现错误,这使更新发生,由于放置在数据库表的deckType上的NOT NULL导致SQL错误。
详细信息...
public class RuleDeckForm
{
private Long id; // might be null or empty if doing an insert
@NotNull(message="deckType cannot be null")
@NotBlank(message="deckType cannot be blank")
@Size(min=1,max=10, message="deckType must be between 1 - 10 characters")
private String deckType;
// constructors, getters, setters, toString, etc ...
}
@Component(value="ruleDeckFormValidator")
public class RuleDeckFormValidator implements org.springframework.validation.Validator
{
private static final Logger logger = LoggerFactory.getLogger( RuleDeckFormValidator.class );
//constructor
public RuleDeckFormValidator() {}
@Override
public boolean supports( Class<?> clazz) {
return RuleDeckForm.class.isAssignableFrom(clazz);
}
@Override
public void validate( Object obj, Errors errors) {
logger.debug("entering RuleDeckFormValidator.validate");
RuleDeckForm ruleDeckForm = (RuleDeckForm) obj;
logger.debug("cast:" + ruleDeckForm.toString());
if( errors.hasErrors()) { // could be a data binding error, could be all sorts of things
logger.debug( "number of errors found: " + errors.getErrorCount());
...
} else {
logger.debug("no validation errors found");
}
logger.debug("exiting RuleDeckFormValidator.validate");
}
}
@Controller
public class BaseController
{
@Autowired
MyService myService;
@Autowired
RuleDeckFormValidator ruleDeckFormValidator;
@InitBinder( value="RuleDeckForm")
protected void initBinder( WebDataBinder binder) {
binder.setValidator( ruleDeckFormValidator);
}
@ModelAttribute("ruleDeckForm")
public RuleDeckForm getRuleDeckForm() {
return new RuleDeckForm();
}
ObjectMapper mapper = new ObjectMapper(); // JSON to/from object or list of objects, which itself an object
@RequestMapping( value="/ruleDeck_insert_update", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity<?> ruleDeckUpdateHander( @RequestBody @ModelAttribute("ruleDeckForm") @Valid RuleDeckForm ruleDeckForm , BindingResult result)
{
ResponseEntity<?> re = null;
RuleDeck = null;
// use @Valid OR this but not both
//is.ruleDeckFormValidator.validate( ruleDeckForm, result);
if( result.hasErrors()) {
logger.debug( "number of errors found: ", result.getErrorCount());
...
re = new ResponseEntity<Errors>( result, HttpStatus.BAD_REQUEST);
} else {
ruleDeck = updateExistingRuleDeck( ruleDeckForm);
re = new ResponseEntity<RuleDeck>( ruleDeck, HttpStatus.OK);
}
return re;
}
}
最后是index.jsp
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<body>
<div id="popupRuleDeck_update" class="popup displayNone">
<div class="form-wrapper">
<form:form id="form_popupRuleDeck_update" modelAttribute="ruleDeckForm" method="post">
<fieldset>
<legend>RuleDeck-update</legend>
<label for="id">id</label>
<form:input id="update-id" path="id" type="number" readonly="readonly"/>
<label for="deckType">deckType</label>
<form:input id="update-deck-type" path="deckType" type="text" /><p>
<form:errors path="deckType" class="help-online"/>
...
<button id="popupRuleDeck_update_submit">Submit</button>
</fieldset>
</form:form>
</div>
</div>
</body>
</html>
<script>
...
function popupRuleDeck_update_submit( event) {
event.preventDefault();
var formJsonObj = $('#form_popupRuleDeck_update').serializeObject();
var formJsonStr = JSON.stringify( formJsonObj);
$.ajax({
url: '${pageContext.request.contextPath}/ruleDeck_insert_update',
type: "post",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: formJsonStr
}).done( function( response, textStatus, jqXHR) {
console.dir( "update succeeded textStatus:" + textStatus);
ruleTable.row('.selected').data( response).invalidate().draw();
}).fail( function( jqXHR, textStatus, errorThrown) {
console.dir( "update failed textStatus:" + textStatus);
console.dir( "update failed errorThrown:" + errorThrown );
var errors = jqXHR.responseJSON;
if( errors) {
console.dir( "failed errors:" + jqXHR.responseJSON);
}
}).always( closeUpdatePopup);
}
...
</script>
因此,大局是让服务器端表单验证可用于插入,更新和删除,并将错误报告回弹出式表单,就像所有这些酷示例一样。关于如何进行的任何想法? this似乎会导致部分答案。here几乎是我要解决的一个问题,但是我确实将hibernate-validator作为我pom中的依赖项。this很好地解释了这三个问题实现验证的方法以及为什么我可能无法获得想要的结果,但是没有解释如何将错误返回到前端的表单中
奖金问题:我已经成为jsfiddle的最新转换者。但是有没有类似的东西可以对服务器端的东西进行建模呢?
TIA,
仍在学习的史蒂夫