`

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看的有点头大

相关推荐

    SpringMVC文档.zip_spring mvc

    5. **Spring MVC 3.x annotated controller的几点心得体会** - 作者可能分享了在实际开发中使用注解控制器的经验和技巧,包括错误处理、数据验证、模型绑定等方面。 6. **SpringMVC数据绑定** - 数据绑定是Spring...

    Manning.Spring.in.Action.4th.Edition.2014.11.epub

    7.1. Alternate Spring MVC configuration 7.1.1. Customizing DispatcherServlet configuration 7.1.2. Adding additional servlets and filters 7.1.3. Declaring DispatcherServlet in web.xml 7.2. Processing ...

    springframework.5.0.12.RELEASE

    Exporting a lazily initialized bean (which implements SelfNaming and is annotated with ManagedResource annotation) gives IllegalStateException [SPR-17592] #22124 MockHttpServletRequest changes Accept-...

    the.annotated.turing

    书中的内容主要围绕以下几个关键知识点展开: 1. **图灵机模型**:图灵机是计算理论的基石,它是一个抽象的计算设备,能够模拟任何算法的逻辑。书中详细介绍了图灵机的工作原理,包括状态、带子、读写头和规则,...

    自动驾驶Apollo源码注释.(annotated Apollo 1.0 source code).zip

    在学习Apollo 1.0源码时,可以关注以下几个关键点: - 数据流处理:了解如何从不同传感器获取原始数据,并将其转化为可供其他模块使用的格式。 - 算法实现:深入研究感知模块中的目标检测算法,如YOLO、Faster R-...

    Margaret A. Ellis, Bjarne Stroustrup-The Annotated C++ Reference Manual

    Margaret A. Ellis, Bjarne Stroustrup-The Annotated C++ Reference Manual

    Addison.Wesley.dot.NET.Framework.Standard.Library.Annotated.Reference.Volume.1.Mar.2004.FIXED [CHM]

    Edited by a Lead Program Manager on Microsoft's .NET Framework team, .NET Framework Standard Library Annotated Reference, Volume 1, is the definitive reference for the .NET Framework base class ...

    spring-mvc序列化json动态擦除属性[参考].pdf

    在Spring MVC中,当需要将Java对象转换为JSON格式发送给客户端时,有时会遇到返回对象包含大量冗余属性的情况,这可能导致不必要的网络流量消耗。为了解决这个问题,我们可以实现一个动态擦除属性的机制,使得在序列...

    Learning Spring Application Development

    Following this, you will explore how to implement the request handling layer using Spring annotated controllers. Other highlights include learning how to build the Java DAO implementation layer by ...

    Learning Spring Application Development(PACKT,2015)

    Following this, you will explore how to implement the request handling layer using Spring annotated controllers. Other highlights include learning how to build the Java DAO implementation layer by ...

    redis-3.0-annotated-unstable.zip

    redis-3.0-annotated-unstable.zipredis-3.0-annotated-unstable.zipredis-3.0-annotated-unstable.zipredis-3.0-annotated-unstable.zip

    Spring+SpringMVC+JPA+Hibernate搭建

    13. 配置控制器(Controller)以处理Web层的请求,并将视图解析器配置到Spring MVC配置文件中,以便Spring MVC框架知道如何渲染视图。 通过上述步骤,可以将Spring、SpringMVC、JPA和Hibernate集成到一起,构建一个...

    spring2.5 jar

    2. **注解驱动开发(Annotated Controllers)**:在Spring 2.5中,可以使用`@Controller`、`@RequestMapping`等注解来声明控制器类和处理HTTP请求的方法,大大简化了Web应用程序的开发。 3. **AOP增强**:Spring ...

    The Annotated C++ Reference Manual.part2

    The Annotated C++ Reference Manual.part2

    人脸数据库 Annotated Database

    在"Annotated Database"中,这些关键点已预先标注,可以用于训练和优化关键点检测算法,如Dlib的HOG(Histogram of Oriented Gradients)或基于深度学习的MTCNN(Multi-task Cascaded Convolutional Networks)。...

    The Annotated C++ Reference Manual.zip.001

    The Annotated C++ Reference Manual

    The Thinking in Java Annotated Solution Guide

    而《The Thinking in Java Annotated Solution Guide》则是对原书习题的详尽解答,帮助读者巩固所学知识并解决实际编程问题。 这个压缩包包含的是书中所有代码示例,对于学习Java编程非常有帮助。以下是这些代码...

    The Annotated C++ Reference Manual.7z.008

    The Annotated C++ Reference Manual (共11部分) 传说中的原版巨作,不差页

Global site tag (gtag.js) - Google Analytics