`

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

阅读更多

最近拿Spring MVC 3.x做项目,用了最新的系列相关Annotation来做Controller,有几点心得体会值得分享。

 

转载请注明 :IT进行时(zhengxianquan AT hotmail.com) from http://itstarting.iteye.com/

 

一、编写一个AbstractController.java,所有的Controller必须扩展

    除了获得Template Design Pattern的好处之外,还能一点,那就是放置全局的@InitBinder:

public class AbstractController {
...
	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class,new CustomDateEditor(dateFormat, false));
	}
...
}


二、每个域都应该有一个Controller,且做好URI规划

    大家都知道Spring MVC 3.x是完全支持Restful的,我们把URI做好规划,对于诸如ACL的实现会有很大的帮助。建议的URI规划如下:{Domain}[/{SubDomain}]/{BusinessAction}/{ID}。比如:

    hotels/bookings/cancel/{id} ——表示此URI匹配hotels域的bookings子域,将要进行的是取消某项booking的操作。代码如下:

@Controller
@RequestMapping(value = "/hotels")
public class HotelsController extends AbstractController {
...
	@RequestMapping(value = "/bookings/cancel/{id}", method = RequestMethod.POST)
	public String deleteBooking(@PathVariable long id) {
		bookingService.cancelBooking(id);
		//use prefix 'redirect' to avoid duplicate submission
		return "redirect:../../search";
	}
...
}
 

 

    另外还有几个重要原因:

    1、由于Spring的DefaultAnnotationHandlerMapping.java在做Mapping的时候,先做是否有类匹配,再找方法,把基本的mapping放在类上面,可以加速匹配效率;

    2、后续可以通过更细腻的支持Ant path style的AntPathMatcher来规划URI Template资源,做ACL控制(请参考后面的心得体会)。


三、JSON/XML等ajax的支持很cool,可以尝试

    JSON/XML/RSS等均可支持,当然有些denpendency,比如JSON的默认支持,需要jackson jar出现在lib中,POM的artifact如下:

<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-mapper-asl</artifactId>
	<version>1.5.3</version>
</dependency>

   这样,我们其实根本就不需要进行额外的JSON转换了,Spring MVC 3会根据请求的格式自行转换:

	@ResponseBody
	@RequestMapping(value = "/ajax", method = RequestMethod.POST)
	public JsonDataWrapper<Hotel> ajax(WebRequest request, Hotel hotel, Model model) 
		throws Exception {
		JsonDataWrapper<Hotel> jsonDataWrapper = this.getPaginatedGridData(request, hotel, hotelService);
		return jsonDataWrapper;
	}

   :我上面的JsonDataWrapper只是我自己做的一个简单的wrapper,目的是为jQuery Flexigrid plugin做数据准备的。还是贴出来吧:

/**
 * A wrapper class for jQuery Flexigrid plugin component.
 * 
 * The format must be like this:
 * <code>
 * 		{"total":2,"page":1,"rows":[
 * 			{"personTitle":"Mr","partyName":"Test8325","personDateOfBirth":"1970-07-12"},
 * 			{"personTitle":"Ms","partyName":"Ms Susan Jones","personDateOfBirth":"1955-11-27"}
 * 		]}
 * </code>
 * 
 * @author bright_zheng
 *
 * @param <T>: the generic type of the specific domain
 */
public class JsonDataWrapper<T> implements Serializable {
	private static final long serialVersionUID = -538629307783721872L;

	public JsonDataWrapper(int total, int page, List<T> rows){
		this.total = total;
		this.page = page;
		this.rows = rows;
	}
	private int total;
	private int page;
	private List<T> rows;
	
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public int getPage() {
		return page;
	}
	public void setPage(int page) {
		this.page = page;
	}
	public List<T> getRows() {
		return rows;
	}
	public void setRows(List<T> rows) {
		this.rows = rows;
	}
}


四、Controller的单元测试变得很可为且简单

    以前的项目从来不做controller层的测试,用了Spring MVC 3这一点就不再难为情,做吧:

public class HotelsControllerTest {
	
	private static HandlerMapping handlerMapping;
	private static HandlerAdapter handlerAdapter;
	
	private static MockServletContext msc;

	@BeforeClass
	public static void setUp() {
		String[] configs = {
				"file:src/main/resources/context-*.xml",
				"file:src/main/webapp/WEB-INF/webapp-servlet.xml" };
		XmlWebApplicationContext context = new XmlWebApplicationContext();  
        context.setConfigLocations(configs);  
        msc = new MockServletContext();  
        context.setServletContext(msc);  
        context.refresh();  
        msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
        ApplicationContextManager manager = new ApplicationContextManager();
		manager.setApplicationContext(context);		
		handlerMapping = (HandlerMapping) ApplicationContextManager.getContext().getBean(DefaultAnnotationHandlerMapping.class);
		handlerAdapter = (HandlerAdapter) ApplicationContextManager.getContext().getBean(ApplicationContextManager.getContext().getBeanNamesForType(AnnotationMethodHandlerAdapter.class)[0]);		
	}

	@Test
	public void list() throws Exception {
		MockHttpServletRequest request = new MockHttpServletRequest();
		MockHttpServletResponse response = new MockHttpServletResponse();
		
		request.setRequestURI("/hotels");
		request.addParameter("booking.id", "1002");
		request.addParameter("hotel.name", "");
		request.setMethod("POST");
		
		//HandlerMapping
		HandlerExecutionChain chain = handlerMapping.getHandler(request);
		Assert.assertEquals(true, chain.getHandler() instanceof HotelsController);
		
		//HandlerAdapter
		final ModelAndView mav = handlerAdapter.handle(request, response, chain.getHandler());
		
		//Assert logic
		Assert.assertEquals("hotels/search", mav.getViewName());
	}
}

    需要说明一下 :由于当前最想版本的Spring(Test) 3.0.5还不支持@ContextConfiguration的注解式context file注入,所以还需要写个setUp处理下,否则类似于Tiles的加载过程会有错误,因为没有ServletContext。3.1的版本应该有更好的解决方案,参见:https://jira.springsource.org/browse/SPR-5243

    Service等其他layer就没有这类问题,测试的写法将变得更加优雅,贴个出来:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/resources/context-*.xml" })
public class DefaultServiceImplTest {
	/** @Autowired works if we put @ContextConfiguration at junit type */
	@Autowired
	@Qualifier("hotelService")
	private HotelService<Hotel> hotelService;

	@Test
	public void insert() {
		Hotel hotel = new Hotel();
		hotel.setAddress("addr");
		hotel.setCity("Singapore");
		hotel.setCountry("Singapore");
		hotel.setName("Great Hotel");
		hotel.setPrice(new BigDecimal(200));
		hotel.setState("Harbarfront");
		hotel.setZip("010024");
		hotelService.insert(hotel);
	}
}
 

五、ACL可以写一个HandlerInterceptorAdapter,在“事前”拦截。

    由于Spring是Restful friendly的framework,做ACL就不要用过滤器了,用interceptor吧:

public class AclInterceptor extends HandlerInterceptorAdapter {
	private static final Logger logger = Logger.getLogger(AclInterceptor.class);
	
	/** default servlet prefix */
	private static final String DEFAULT_SERVLET_PREFIX = "/servlet";
	
	/** will be injected from context configuration file */
	private AclService service;
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		String currentUri = request.getRequestURI();
		boolean isAccessible = true;
		//only intercept for annotated business controllers
		Controller c = AnnotationUtils.findAnnotation(handler.getClass(), Controller.class);
		if(c!=null){
			String[] grantedResource = getGrantedResource(request);
			if(grantedResource==null || grantedResource.length==0){
				throw new AccessDeniedException("No resource granted");
			}
			isAccessible = service.isAccessible(grantedResource, currentUri);
			if(logger.isDebugEnabled()){
				logger.debug("ACL interceptor excueted. Accessible for Uri[" + currentUri +"] = " + isAccessible);
			}
			//if isAccessible==true, throw custom AccessDeniedException
			if(!isAccessible) throw new AccessDeniedException();
		}
		return isAccessible;
	}
	
	/**
	 * transfer the original Uri to resource Uri
	 * e.g.:
	 * 	original Uri: /servlet/hotels/ajax
	 * 	target Uri  : /hotels/ajax
	 * @param originalUri
	 * @return
	 */
	protected String getUri(String originalUri){
		return originalUri.substring(DEFAULT_SERVLET_PREFIX.length());
	}
	
	/**
	 * Get the granted resource from session
	 * @param request
	 * @return
	 */
	protected String[] getGrantedResource(HttpServletRequest request){
		//get the resources from current session
		//String[] uriResourcePattern = (String[]) request.getSession().getAttribute("uriResourcePattern");		
		//TODO: mock data here
		String[] uriResourcePattern = new String[]{"/**"};
		
		return uriResourcePattern;
	}

	public void setService(AclService service) {
		this.service = service;
	}
}

    :上面还有TODO部分,很简单,登录后把当然用户可访问的Ant path style的URI Resources放到session中,作为一个String[],这里拿来出匹配即可,建议匹配就用org.springframework.util.AntPathMatcher。

 

六、对于Ajax Form Validation,正在寻求更佳的解禁方案。

    Spring 3已经支持@Valid的注解式validation,又一个JSR,但通过我研究代码发现,默认的org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.java实现还是非常封闭,并不能很好的实现binding后执行业务代码前处理,所以目前的实现办法还不算优雅。

    已经实现,大致的思路是:

    1)发出ajax form post请求(用jQuery);

    2)正常mapping到controller的方法中处理;

    3)做form validation;

    4)不管怎样,forward到一个解析错误消息的JSP,叫ajaxFormValidatorResult.jsp;

    5)再写一个jquery plugin,叫errorBinder.js,解析错误并自定binding为Tooltip,如果没错误就正常submit

贴个简单的demo效果,欢迎拍砖。

  ==Before


  ==After


 

 

补充说明:后面陆续补充的心得,就不在这里出现了,而是以跟帖的形式存在,便于讨论吧

 

  • 大小: 4 KB
  • 大小: 8.2 KB
分享到:
评论
80 楼 itstarting 2011-05-30  
jason&xu 写道
感觉SPRING MVC的数据绑定比较差,没struts2方便。

楼上可否举例一二加以说明?

据我所知,spring mvc的form binding和validation都还是不错的了

其中的form binding只要加上一个model,即可完全面向pojo对象实现form <-> controller param之间的绑定与传递

struts2一直没兴趣看,也就不得而知其高明之处了,还请指教
79 楼 jason&xu 2011-05-29  
感觉SPRING MVC的数据绑定比较差,没struts2方便。
78 楼 itstarting 2011-05-29  
kjj 写道
虽然没用springmvc但是最后还是我一票,定为精华了,楼主的确认认真,建议分片,分类整理成博客,便于后来人学习!!!

哈哈,谢谢了,我还一直奇怪怎样才能捞个精华呢

不过也说明spring mvc还是有其可取之处,哪怕相比struts
77 楼 kjj 2011-05-29  
虽然没用springmvc但是最后还是我一票,定为精华了,楼主的确认认真,建议分片,分类整理成博客,便于后来人学习!!!
76 楼 itstarting 2011-05-26  
<div class="quote_title">itstarting 写道</div><div class="quote_div"><div class="quote_title">suyulin6688 写道</div>
<div class="quote_div">
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<div class="quote_div">
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
</div>
<p> </p>
<p>我的作法是在 webapp 根目录下,建一个子目录 resources ,</p>
<p>在 resources 下,再建 3 个子目录:js, css, img</p>
<p> </p>
<p>在 spring mvc 的 xml 配置文件里面,加上这一句:</p>
<p>&lt;mvc:resources location="/resources/" mapping="/resources/**" /&gt;</p>
<p> </p>
<p>web.xml 里面,还是配置:</p>
<p>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
<p> </p>
<p>这样达到的效果:spring mvc 处理所有请求,但是 resources 下的(js, css, img)除外。</p>
</div>
<p> </p>
<p>既然楼上的说开了,我就补充一下,我的思路跟你一样,只是我直接把js,css,images直接放到根目录下,然后这样配置:</p>
<p>
</p>
<pre name="code" class="xml">&lt;mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" /&gt;</pre>

<p> </p>
<p>好处也说一下,免得越抹越黑,浪费大家笔墨:</p>
<p>1. 因为jsp,message,tld等都放到了WEB-INF下,其实根目录下本来就没啥东西了,所以js,css,images就直接摆出来了;</p>
<p>2. 因为用了spring的js/resource组件(org.springframework.js.resource.ResourceServlet @ spring-js-resource),这东西可以把jar的东西也按需export出来,有利于组件化——比如有些img是framework级别的,一般基于此framework的项目就直接export出来用好了</p></div><br/>再补充一点,用了spring-js-resource 还可以配置更精准的resource cache策略,也是很有意思的一点,具体请大家看ref吧
75 楼 itstarting 2011-05-26  
<div class="quote_title">suyulin6688 写道</div>
<div class="quote_div">
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<div class="quote_div">
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
</div>
<p> </p>
<p>我的作法是在 webapp 根目录下,建一个子目录 resources ,</p>
<p>在 resources 下,再建 3 个子目录:js, css, img</p>
<p> </p>
<p>在 spring mvc 的 xml 配置文件里面,加上这一句:</p>
<p>&lt;mvc:resources location="/resources/" mapping="/resources/**" /&gt;</p>
<p> </p>
<p>web.xml 里面,还是配置:</p>
<p>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
<p> </p>
<p>这样达到的效果:spring mvc 处理所有请求,但是 resources 下的(js, css, img)除外。</p>
</div>
<p> </p>
<p>既然楼上的说开了,我就补充一下,我的思路跟你一样,只是我直接把js,css,images直接放到根目录下,然后这样配置:</p>
<p>
</p>
<pre name="code" class="xml">&lt;mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/web-resources/" /&gt;</pre>

<p> </p>
<p>好处也说一下,免得越抹越黑,浪费大家笔墨:</p>
<p>1. 因为jsp,message,tld等都放到了WEB-INF下,其实根目录下本来就没啥东西了,所以js,css,images就直接摆出来了;</p>
<p>2. 因为用了spring的js/resource组件(org.springframework.js.resource.ResourceServlet @ spring-js-resource),这东西可以把jar的东西也按需export出来,有利于组件化——比如有些img是framework级别的,一般基于此framework的项目就直接export出来用好了</p>
74 楼 suyulin6688 2011-05-26  
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<div class="quote_div">
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
</div>
<p>
</p>
<p>我的作法是在 webapp 根目录下,建一个子目录 resources ,</p>
<p>在 resources 下,再建 3 个子目录:js, css, img</p>
<p> </p>
<p>在 spring mvc 的 xml 配置文件里面,加上这一句:</p>
<p>&lt;mvc:resources location="/resources/" mapping="/resources/**" /&gt;</p>
<p> </p>
<p>web.xml 里面,还是配置:</p>
<p>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
<p> </p>
<p>这样达到的效果:spring mvc 处理所有请求,但是 resources 下的(js, css, img)除外。</p>
73 楼 itstarting 2011-05-25  
<div class="quote_title">rocketball 写道</div>
<div class="quote_div">
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<div class="quote_div">
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
</div>
<p>再写一个&lt;servlet-mapping&gt; 呗,再说了一般项目还挺难做到全部rest风格吧</p>
<p>比如</p>
<p> </p>
<p>&lt;servlet-mapping&gt;    </p>
<p>    <span style="white-space: pre;"> </span>&lt;servlet-name&gt;default&lt;/servlet-name&gt;    </p>
<p>    <span style="white-space: pre;"> </span>&lt;url-pattern&gt;/css/*&lt;/url-pattern&gt;    </p>
<p>&lt;/servlet-mapping&gt; </p>
</div>
<p> </p>
<p>
</p>
<p>楼上说的对,我也是建议使用起码两个servlet mapping,下面是我的建议用法:</p>
<p>
</p>
<pre name="code" class="xml">  &lt;!-- Serves static resource content from .jar files such as spring-faces.jar --&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;Resources Servlet&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.springframework.js.resource.ResourceServlet&lt;/servlet-class&gt;
&lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
&lt;/servlet&gt;

&lt;!-- Map all /resources requests to the Resource Servlet for handling --&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;Resources Servlet&lt;/servlet-name&gt;
&lt;url-pattern&gt;/resources/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;

&lt;!-- The front controller of this Spring Web application, responsible for handling all application requests --&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;Controller&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
&lt;param-value&gt;
/WEB-INF/webapp-servlet.xml
&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;

&lt;!-- Map all requests to the DispatcherServlet for handling --&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;Controller&lt;/servlet-name&gt;
&lt;url-pattern&gt;/servlet/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
 
<div>一个用来mapping resource(这样用甚至可以map到jar里面的资源),另一个专门mapping servlet.</div>
<div><br></div>
72 楼 rocketball 2011-05-25  
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<div class="quote_div">
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
</div>
<p>再写一个&lt;servlet-mapping&gt; 呗,再说了一般项目还挺难做到全部rest风格吧</p>
<p>比如</p>
<p>
</p>
<p>&lt;servlet-mapping&gt;    </p>
<p>    <span style="white-space: pre;"> </span>&lt;servlet-name&gt;default&lt;/servlet-name&gt;    </p>
<p>    <span style="white-space: pre;"> </span>&lt;url-pattern&gt;/css/*&lt;/url-pattern&gt;    </p>
<p>&lt;/servlet-mapping&gt; </p>
71 楼 yinyanbin 2011-05-25  
<div class="quote_title">rocketball 写道</div>
<div class="quote_div">
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<p>楼主你好,有个问题咨询下,如果采用rest的url方式的话,在配置web.xml的时候需要怎么配置呢?<br>我现在是这样配置的:</p>
<p> </p>
<pre name="code" class="xml">&lt;servlet&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;servlet-class&gt;
org.springframework.web.servlet.DispatcherServlet
&lt;/servlet-class&gt;
        &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
 
<p> 如过要采用rest的方式的话  url-pattern要怎么写呢?/*吗?还是?</p>
</div>
<p>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
<p>再加上</p>
<p> </p>
<p>&lt;filter&gt;  </p>
<p>     <span style="white-space: pre;"> </span>&lt;filter-name&gt;HiddenHttpMethodFilter&lt;/filter-name&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;filter-class&gt;org.springframework.web.filter.HiddenHttpMethodFilter&lt;/filter-class&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;/filter&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;filter-mapping&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;filter-name&gt;HiddenHttpMethodFilter&lt;/filter-name&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;/filter-mapping&gt; </p>
<p>已支持put跟delete方法</p>
</div>
<p>如果是&lt;url-pattern&gt;/&lt;/url-pattern&gt;那么图片,css,js怎么办呢?就显示不了了</p>
70 楼 rocketball 2011-05-25  
<div class="quote_title">yinyanbin 写道</div>
<div class="quote_div">
<p>楼主你好,有个问题咨询下,如果采用rest的url方式的话,在配置web.xml的时候需要怎么配置呢?<br>我现在是这样配置的:</p>
<p> </p>
<pre name="code" class="xml">&lt;servlet&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;servlet-class&gt;
org.springframework.web.servlet.DispatcherServlet
&lt;/servlet-class&gt;
        &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
 
<p> 如过要采用rest的方式的话  url-pattern要怎么写呢?/*吗?还是?</p>
</div>
<p>&lt;url-pattern&gt;/&lt;/url-pattern&gt;</p>
<p>再加上</p>
<p>
</p>
<p>&lt;filter&gt;  </p>
<p>     <span style="white-space: pre;"> </span>&lt;filter-name&gt;HiddenHttpMethodFilter&lt;/filter-name&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;filter-class&gt;org.springframework.web.filter.HiddenHttpMethodFilter&lt;/filter-class&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;/filter&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;filter-mapping&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;filter-name&gt;HiddenHttpMethodFilter&lt;/filter-name&gt;  </p>
<p>    <span style="white-space: pre;"> </span>&lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;  </p>
<p><span style="white-space: pre;"> </span>&lt;/filter-mapping&gt; </p>
<p>已支持put跟delete方法</p>
69 楼 yinyanbin 2011-05-25  
<p>楼主你好,有个问题咨询下,如果采用rest的url方式的话,在配置web.xml的时候需要怎么配置呢?<br>我现在是这样配置的:</p>
<p>
</p>
<pre name="code" class="xml">&lt;servlet&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;servlet-class&gt;
org.springframework.web.servlet.DispatcherServlet
&lt;/servlet-class&gt;
        &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;background&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
 
<p> 如过要采用rest的方式的话  url-pattern要怎么写呢?/*吗?还是?</p>
68 楼 itstarting 2011-05-19  
pchg119 写道
我不是来灌水的
只是看到这个目前网络流行的一塌糊涂的 springmvc就喜欢看看
做商务网站是用spring好还是不用好呢?

商务网站要考虑的东西更多,比如横向/纵向扩展、缓存、可用性、可维护性……注入此类,简单一句用不用spring解决不了问题

用spring更多是考虑研发的绩效问题,至于“商务网站”,综合考虑再说吧,感觉与spring没太直接关系
67 楼 pchg119 2011-05-19  
我不是来灌水的
只是看到这个目前网络流行的一塌糊涂的 springmvc就喜欢看看
做商务网站是用spring好还是不用好呢?
66 楼 haitaohehe 2011-05-17  
楼主能否提供下spring mvc本身验证的例子,对于jsr303个人感觉倾入性太大,官方的例子好像就是基于jsr303的...
65 楼 yin_bp 2011-05-06  
大家讨论了这么多收益匪浅,不过还是建议大家看看bbossgroups项目,呵呵,有demo,有eclipse工程,丰富的数据绑定参数机制,没有这么多的注解,学习成本低,容易上手,能够解决实际问题,呵呵,spring mvc没法比,详情请看官方博客:
http://yin-bp.iteye.com/
64 楼 itstarting 2011-03-23  
muqingren 写道
楼主请教
@SessionAttributes(types=UserInfoVo.class,value="userinfo")

我用这个注解后,运行提示我:
org.springframework.web.HttpSessionRequiredException: Session attribute 'userinfo' required - not found in session


这是为什么??谢谢

提示很清楚呀:你需要的属性为userinfo的session对象不存在

是否有optional=true之类的属性可以用用,试一下咯
63 楼 muqingren 2011-03-18  
楼主请教
@SessionAttributes(types=UserInfoVo.class,value="userinfo")

我用这个注解后,运行提示我:
org.springframework.web.HttpSessionRequiredException: Session attribute 'userinfo' required - not found in session


这是为什么??谢谢
62 楼 itstarting 2011-03-18  
自学得1)搞清楚自己要什么;2)找对资料;3)可以应用并持续解决问题
61 楼 njbble 2011-03-17  
kongruxi 写道
楼主写得不错啊,我也正在学spring MVC 3
不过,我看了一下spring 3 API,发现很多Controler都变为Deprecated,建议用注解代替。但不清楚AbstractWizardFormController这个怎样用注解来代替?请教楼主了……

是啊,自学API看的有点头大

相关推荐

Global site tag (gtag.js) - Google Analytics