spring(一)
maven依赖的jar的查询
进去http://www.mvnrepository.com/,搜索jackson,然后就会列出来jackson相关的jar,点进去就会有依赖,复制就行了。
spring 配置信息:
1.在spring的xml文件中使用<context:property-placeholder>标签导入properties文件=>
在spring配置中因为spring容器采用反射扫描的发现机制,所以当Spring探测到容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderCVonfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描,即只能存在一个实例。
那如果有多个配置文件怎么办呢?那就多个文件之间以“,”分隔,如下:
<context:property-placeholderlocation="classpath:db.properties,classpath:monitor.properties" />
值得注意的是:多个配置文件将依次加载,如果后一个文件中有和前面某一个文件中属性名是相同的,最终取的值是后加载的值。
2.spring 扫描组件<context:component-scan base-package=" "/>的使用详解=>
如果不想在spring的配置中配置bean,我们可以给我们的类上加上spring的组件注解,只需要配置下spring的扫描器就可以实现bean的自动载入。
base-package表明需要扫描的包
如果在需要扫描的包的其中的某个类上带有特定的注解 @component @repository@service ,
@controller,就会将这个对象作为bean注入spring容器。
有了<context:component-scan>,另一个<context:annotation-config/>标签就可以移除掉,因为已经被包含进去了。
<context:component-scan>提供两个子标签:<context:include-filter>和<context:exclude-filter>各代表引入和排除的过滤。
3.
springmvc 的配置
(一).解决springweb捕获静态资源的请求的问题
优雅REST风格的资源URL不希望带 .html 或 .do 等后缀.由于早期的Spring MVC不能很好地处理静态资源,所以在web.xml中配置DispatcherServlet的请求映射,往往使用 *.do 、 *.xhtml等方式。这就决定了请求URL必须是一个带后缀的URL,而无法采用真正的REST风格的URL。
如果将DispatcherServlet请求映射配置为"/",则Spring MVC将捕获Web容器所有的请求,包括静态资源的请求,Spring MVC会将它们当成一个普通请求处理,因此找不到对应处理器将导致错误。
使springmvc截获所有的请求
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
为了解决springweb捕获静态资源的请求的问题,给出了两种的解决方案:
1.采用 <mvc:default-servlet-handler />
2.采用<mvc:resources/>
在springMVC-servlet.xml中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
一般Web应用服务器默认的Servlet名称是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />
首先,<mvc:resources />允许静态资源放在任何地方,如WEB-INF目录下、类路径下等,你甚至可以将JavaScript等静态文件打到JAR包中。通过location属性指定静态资源的位置,由于location属性是Resources类型,因此可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制。
在springMVC-servlet中添加如下配置:
<mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>
以上配置将Web根路径"/"及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径。假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件,则可以通过 /resources/images/bg.gif 和 /resources/js/test.js 访问这二个静态资源。
假设WebRoot还拥有images/bg1.gif 及 js/test1.js,则也可以在网页中通过 /resources/images/bg1.gif 及 /resources/js/test1.js 进行引用。
(二).<mvc:annotation-driven>
<mvc:annotation-driven>会自动注RequestMappingHandlerMapping和RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,并且提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持读写XML的支持(JAXB)和读写JSON的支持(默认Jackson)等功能。
Spring MVC @ResponseBody响应中文乱码
问题:
在前端通过get请求服务端返回String类型的服务时,会出现中文乱码问题
原因:
由于spring默认对String类型的返回的编码采用的是 StringHttpMessageConverter
>>> spring mvc的一个bug,spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list则使用MappingJacksonHttpMessageConverter,返回string,则使用StringHttpMessageConverter,这个convert使用的是字符集是iso-8859-1,而且是final的:
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
解决办法:
方案一:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
@responsebody
这个注解表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用。
在使用@RequestMapping后,返回值通常解析为跳转路径。加上@responsebody后,返回结果直接写入HTTP response body中,不会被解析为跳转路径。比如异步请求,希望响应的结果是json数据,那么加上@responsebody后,就会直接返回json数据。
=》springmvc的跳转情况分析
1、直接转跳页面(不传参)
1》使用@requestmapping 并返回要转跳页面的名称
2、带参转跳页面
带参方式:
1》使用@requestmapping 使用modlemap map map.addattribute("","");
2》使用@requestmapping 使用modleandview
3》使用@requestmapping 使用@RequestBody 对象 对象名
以上一定要返回要转跳页面的名称
3、传参回请求页面(ajax)
加上注解@reponsebody,就会直接返回json数据。
=》@ModelAttribute注解用法
@ModelAttribute使用大致有有两种,一种是是直接标记在方法上,一种是标记在方法的参数中
1、@modelattribute直接标记在方法上
情况一:@ModelAttribute标记方法无返回值
当同一个controller中有任意一个方法被@ModelAttribute注解标记,页面请求只要进入这个控制器,不管请求那个方法,均会先执行被@ModelAttribute标记的方法,所以我们可以用@ModelAttribute注解的方法做一些初始化操作。当同一个controller中有多个方法被@ModelAttribute注解标记,所有被@ModelAttribute标记的方法均会被执行,按先后顺序执行,然后再进入请求的方法。
@ModelAttribute
public void init(Model mode)
{
PojoTest pojo=new PojoTest(null, "小明", "男");
mode.addAttribute("pojo", pojo);
}
@RequestMapping(value="modelTest.do")
public String modelTest()
{
return "modelTest";
}
这样当请求modeltest.do时会先执行被@modelattribute注解的init方法。因为model模型数据与request作用域相同,所以会把model中的数据带到modeltest.do请求的地址页面中去。
情况二:@ModelAttribute标记方法有返回值
@ModelAttribute
public String init(Model mode)
{
System.out.println("进入init方法");
PojoTest pojo=new PojoTest(null, "小明", "男");
mode.addAttribute("pojo", pojo);
return "model/befor.do";
}
@RequestMapping(value="befor.do")
public String befor(){
System.out.println("进入befor方法");
return "index";
}
@RequestMapping(value="modelTest.do")
public String modelTest()
{
System.out.println("进入modelTest方法");
return "modelTest";
}
可以看到init方法中有返回值 return "model/befor.do";
但是实际请求的地址是modeltest.do 程序会在return "model/befor.do";之前直接转跳实际请求的方法。
情况三:当@RequestMapping标记和@ModelAttribute同时标记在一个方法上
@Controller
public class ModelAttributeTest {
@RequestMapping(value="modelTest.do")
@ModelAttribute(value="pojo")
public String modelTest()
{
System.out.println("进入modelTest方法");
return "modelTest";
}
}
<script type="text/javascript">
$(function(){
$("#modelTest").on("click",function(){
window.location.href="<%=basePath%>modelTest.do";
})
});
</script>
<body>
<input type="button" id="modelTest" value="测试">
<input type="text" value="${pojo }">
</body>
点击测试页面,会发现当两个注解同时注解到一个方法上时,方法的返回值会变成model模型的返回值,key是标记的名
情况四:@ModelAttribute("pojo") 在方法的参数列表中。
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@ModelAttribute("pojo")
public PojoTest init( PojoTest pojo)
{
pojo.setSex("男");
return pojo;
}
@RequestMapping(value="modelTest.do")
public String modelTest(@ModelAttribute("pojo") PojoTest pojo)
{
pojo.setUserName("小明");
return "modelTest";
}
}
点击测试发现,modelTest拿到inint方法中的pojo对象,合并两次set的参数后返回页面 @ModelAttribute("pojo")可以指定返回页面上对象的名称。