论坛首页 Java企业应用论坛

Spring MVC 3.x annotated controller的几点心得体会

浏览 58627 次
该帖已经被评为精华帖
作者 正文
   发表时间:2010-12-16  
unsid 写道

感谢楼主回复,按照上面的配置方法
<form:form method="post" modelAttribute="CustomerCommand" action="/xrequirement/addcustomer.do">
我出了一个错误,说没有绑定'CustomerCommand'
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'CustomerCommand' available as request attribute
我突然想到一个问题,如果我的CustomerCommand.class在com.command.CustomerCommand,modelAttribute怎么知道去这个路径找到并实例化CustomerCommand?是不是哪还少配置了什么?


需要你把controller对应的方法也贴出来,咋一看还真不知道,如果你的controller的方法为:
@RequestMapping(value="/xrequirement/addcustomer.do")
public void addcustomer(WebRequest request, CustomerCommand command, Model model){
...
}

应该可以的吧。

还有,会不会是
modelAttribute="CustomerCommand"
改为
modelAttribute="customerCommand"
0 请登录后投票
   发表时间:2010-12-16  
	<form:form method="post" modelAttribute="customerCommand" action="/xrequirement/addcustomer.do">
	${hello}<br>
	FIRSTNAME: <form:input path="firstname"/><br>
	LASTNAME:  <form:input path="lastname"/><br>
	<input type="submit" value="regist"/>
	</form:form>


这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下?
0 请登录后投票
   发表时间:2010-12-17  
unsid 写道
	<form:form method="post" modelAttribute="customerCommand" action="/xrequirement/addcustomer.do">
	${hello}<br>
	FIRSTNAME: <form:input path="firstname"/><br>
	LASTNAME:  <form:input path="lastname"/><br>
	<input type="submit" value="regist"/>
	</form:form>


这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下?

我明白你的意思了。
以前的simpleFormController可以实现同一个url处理一个表单的显示和提交,估计改成annotation模式以后不行了,需要分成两个方法和url处理了。
0 请登录后投票
   发表时间:2010-12-17  
unsid 写道

这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下?



你把相关代码贴出来,这个问题不应该是个棘手问题,肯定是哪里犯了低级错误。
代码包括:
1. CustomerComand.java
2. 在controller的addcustomer方法
3. 加上这个jsp的form,就OK了
0 请登录后投票
   发表时间:2010-12-17  
daquan198163 写道

以前的simpleFormController可以实现同一个url处理一个表单的显示和提交,估计改成annotation模式以后不行了,需要分成两个方法和url处理了。


那如何区分是显示还是提交呢,难道还要专门有个什么flag?
因为一般的页面初始化,也要做少量的就绪逻辑吧,难道直接访问jsp不经controller,然后submit才到controller?

我倒是没注意通过类似于直接越过我们的controller而直接到view的,比如这样配置:
<mvc:view-controller path="/intro" />


我倒是想找时间试一下。
0 请登录后投票
   发表时间:2010-12-17   最后修改:2010-12-17
to楼上:通过请求类型区分,get就是显示表单(a显示一张空的form或显示一个已有的数据表单),post就是提交保存。
0 请登录后投票
   发表时间:2010-12-17  
toitstarting:我在本贴第2页倒数第3楼问的问题你还没解答呢:)
0 请登录后投票
   发表时间:2010-12-17  
哈哈,你够执着的,sorry,我可能没注意你的这个回复。
我逐一说说吧,欢迎探讨

daquan198163 写道

那这样的话,原来与simpleFormController配合使用的validator怎么弄呢?
还有,前面littcai问的问题好像没有被证明解答,我也有同样疑问:


Validation在Spring MVC 3.X上变得非常flexible,一般而言有两种方法:
1、遵循@Valid的注解式validation,此为JSR-303 Bean Validation API,其实与Spring没有啥关系,就是把annotation放到bean中,根据annotation的规则定义进行“自动化”校验——老实说不是特别喜欢,感觉可控性差一些;
2、自己写个validator,注意此时不再需要实现特定的接口咯,比如这样就可以:
public class HotelQueryValidator{
	public void validate(Hotel hotel, Errors errors) {
		if(StringUtils.isEmpty(hotel.getName())){
			//demo for multiple message
			//global error, and this message doesn't exist in file
			errors.reject("form.global.error", "Errors found by form validation");
			
			//field error by rejectValue(...)
			errors.rejectValue("hotel.name", "hotel.query.keyword.required");
			errors.rejectValue("hotel.name", "hotel.query.keyword.size",new Object[]{"1","10"},null);			
		}		
	}
}

然后在controller的方法中调用即可,其原理无非是校验-》网errors加错误,错误一般有两大类:global error用reject,field error用rejectValue。
当然了,自己用一些必要的pattern去写一套简单的validator工具也是推荐的,从我看来。

daquan198163 写道

ExceptionHandler似乎只能处理普通请求(处理方式是跳转到特定错误页面),但是对ajax请求就不行了,无法返回包含错误信息的json。


在Spring MVC 3.x世界里,ajax跟一般的request几乎没有任何区别,你可以:
1、按照正常的validation去做,然后看到有error后,构建你需要的json,比如{"isError":"true"},当然了,最好写一个简单的bean,put进去然后直接return,Spring MVC会帮我们转换为json格式的了
2、显示throw naming exception,然后用ExceptionHandler捕获并采用特定的view来显示
0 请登录后投票
   发表时间:2010-12-17  
明白了,呵呵,谢谢你耐心解答。
看来SpringMVC3.x变得灵活多了,我以前用过一段时间2.x,所以习惯了返回ModelAndView的那个思路,有点转不过来弯。
0 请登录后投票
   发表时间:2010-12-17  
itstarting 写道
unsid 写道

这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下?



你把相关代码贴出来,这个问题不应该是个棘手问题,肯定是哪里犯了低级错误。
代码包括:
1. CustomerComand.java
2. 在controller的addcustomer方法
3. 加上这个jsp的form,就OK了


好的

CustomerComand.java
    public class CustomerCommand {
	
	private String firstname ;
	private String lastname ;
	
	public String getFirstname() {
		return firstname;
	}
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
	public String getLastname() {
		return lastname;
	}
	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
    }


在controller的addcustomer方法
@Controller
   public class CustomerController {
	
	private CustomerRepository customerRepository;
	
	@RequestMapping(value="/addcustomer",method = RequestMethod.GET)
	public String addCustomer(CustomerCommand customerCommand) throws Exception {
             //do something
	}
	
	public void setCustomerRepository(CustomerRepository customerRepository) {
		this.customerRepository = customerRepository;
	}
	
   }


加上这个jsp的form
	<form:form method="post" modelAttribute="customerCommand" action="/addcustomer.do">
	FIRSTNAME: <form:input path="firstname"/><br>
	LASTNAME:  <form:input path="lastname"/><br>
	<input type="submit" value="regist"/>
	</form:form>


非常感谢楼主细心解答!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics