SpringMVC知识集锦
基于仿冒的SpringMVC测试用例示意
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
package cc.gmem.demo.ctrl; import static org.junit.Assert.*; import javax.inject.Inject; import net.greenmemory.commons.lang.StringUtils; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.LoggerFactory; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import com.fasterxml.jackson.databind.ObjectMapper; @RunWith ( SpringJUnit4ClassRunner.class ) @ContextConfiguration ( locations = { "/spring-classgen-disabled.xml", "/spring-mvc.xml" } ) @TransactionConfiguration ( transactionManager = "txManager", defaultRollback = true ) public class SpringMVCControllerTest { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger( SpringMVCControllerTest.class ); @Inject private RequestMappingHandlerAdapter handlerAdapter; @Inject private RequestMappingHandlerMapping handlerMapping; @Inject private SessionFactory sf; @Inject private ObjectMapper om; private MockHttpServletRequest request; private MockHttpServletResponse response; @Before @Transactional public void setUp() { request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); Session sess = sf.getCurrentSession(); } @Test @Transactional public void testController() throws Exception { request.setRequestURI( "/uri/" ); //设置请求的URI Object handler = handlerMapping.getHandler( request ).getHandler(); //获取Handler对象(就是控制器类) handlerAdapter.handle( request, response, handler ); //转发给Handler处理,并获取响应 String contentType = response.getContentType(); String json = response.getContentAsString(); assertTrue( StringUtils.containsIgnoreCase( contentType, "json" ) ); assertTrue( StringUtils.containsIgnoreCase( contentType, "utf-8" ) ); } } |
常用问题
强制产生JSON格式的结果
配置 @RequestMapping( produces = "application/json" )
SpringMVC 设置 /* 过滤全部,导致JSP无法显示的问题
1 2 3 4 |
<!--下面的URL模式会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)--> <url-pattern>/*</url-pattern> <!--解决:下面会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url--> <url-pattern>/</url-pattern> |
找不到控制器类的问题:No mapping found for HTTP request with URI
- 注意URL拦截的前置部分,如/admin,不要再控制器的映射路径中体现,例如地址/admin/user在控制器中直接配: /user
1<url-pattern>/admin/*</url-pattern>
使用Ajax配合@ResponseBody时出现乱码
要注意JavaScript组件的编码问题,例如使用ExtJS的时候可以这样设置:
1 2 3 4 |
Ext.Ajax.defaultHeaders = { 'Accept' : 'application/json', 'Accept-Charset' : 'UTF-8' }; |
SpringMVC重复扫描Spring配置中的包导致错误
可能报错:
org.hibernate.HibernateException: No Session found for current thread
SpringMVC作为子ApplicationContext时,不要扫描应用层的任何类,只扫描MVC控制器。可以把控制器全部放在ctrl包里面,并设置Spring扫描规则:
1 2 3 |
<context:component-scan base-package="cc.gmem.demo.ctrl"> <context:exclude-filter type="annotation" expression="org.springframework.context.annotation.Configuration" /> </context:component-scan> |
Leave a Reply