常用注解
@Controller 控制层,里面有多个连接
@Service 业务层,一般对于接口和实现,如果实现有多个
@Qualifier 如果一个接口有多个实现,那么注入时候加上唯一标识
@Repository 一般的dao
@Autowired 自动注入依赖
@RequestMapping(value = "", method = { RequestMethod.GET, RequestMethod.POST }) 绑定url
@RequestParam(value="XXX",required=false) 绑定参数,
@ResponseBody:返回类型不是HTML 一般都是对应ajax
@ModelAttribute 一般用于controller层,被注解的方法会在所有mapping执行之前执行,并且可以绑定参数到Model model 里面
@Transactional(readOnly = true) 注解式事务
@Value("${**}") 可以注入properties里面的配置项
@ControllerAdvice,是spring3.2提供的新注解,从名字上可以看出大体意思是控制器增
@ExceptionHandler:如果在controller方法遇到异常,就会调用含有此注解的方法。 比如搞一个邮件通知啊
@InitBinder:一般用于controller可以将所有form 将所有传递进来的String进行HTML编码,防止XSS攻击。比如可以将字符串类型的日期转换成date类型
restful风格的连接
@RequestMapping(value = "{className}/{jspName}/addsave", method = { RequestMethod.POST })
public String functionName(@PathVariable String className, @PathVariable String jspName)
@RequestParam 如果参数为空 默认赋值null
“Consider declaring it as object wrapper for the corresponding primitive type.”建议使用包装类型代替基本类型,如使用“Integer”代替“int”
@ControllerAdvice:即把@ControllerAdvice注解内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法。非常简单,不过只有当使用@ExceptionHandler最有用,另外两个用处不大。但是这是针对所有controller的,可以避免我们手动去继承。来一个例子就好懂咯
如果只用需要在spring-mvc.xml里面增加扫描。
<context:component-scan base-package="com.sishuok.es" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
@ResponseBody:
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机: 返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
HttpMessageConverter
mvc:annotation-driven配置
<mvc:annotation-driven >:
是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
后面,我们处理响应ajax请求时,就使用到了对json的支持。
后面,对action写JUnit单元测试时,要从spring IOC容器中取DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,来完成测试,取的时候要知道是<mvc:annotation-driven />这一句注册的这两个bean。
也就是说mvc:default-servlet-handler相当于写了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter
以及MappingJacksonHttpMessageConverter
annotation-driven缺省注册类的改变
Spring 3.0.x中使用了annotation-driven后,缺省使用DefaultAnnotationHandlerMapping 来注册handler method和request的mapping关系。 AnnotationMethodHandlerAdapter来在实际调用handlermethod前对其参数进行处理。
在spring mvc 3.1中,对应变更为
DefaultAnnotationHandlerMapping -> RequestMappingHandlerMapping
AnnotationMethodHandlerAdapter -> RequestMappingHandlerAdapter
AnnotationMethodHandlerExceptionResolver -> ExceptionHandlerExceptionResolver
以上都在使用了annotation-driven后自动注册。
而且对应分别提供了AbstractHandlerMethodMapping , AbstractHandlerMethodAdapter和 AbstractHandlerMethodExceptionResolver以便于让用户更方便的实现自定义的实现类。
<mvc:annotation-driven/>相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个bean,配置一些messageconverter。即解决了@Controller注解的使用前提配置。
@ResponseBody,@RequestBody
@RequestBody 将HTTP请求正文转换为适合的HttpMessageConverter对象。
@ResponseBody 将内容或对象作为 HTTP 响应正文返回,并调用适合HttpMessageConverter的Adapter转换对象,写入输出流。
HttpMessageConverter接口,需要开启<mvc:annotation-driven />。
AnnotationMethodHandlerAdapter将会初始化7个转换器,可以通过调用AnnotationMethodHandlerAdapter的getMessageConverts()方法来获取转换器的一个集合 List<HttpMessageConverter>
有时候我们ajax传给后台的是具体的值比如
http://localhost:8088/generateCode-platform/msok/web/json?name=gao&value=1
后台接收后就自动转换成对象,然后返回object 自动转换成json.
restful风格可以利用http提交工具测试例如
[SendHttpTool 点击进入网盘下载] (http://pan.baidu.com/s/1o6BYE0q)
@ResponseBody
@RequestMapping(value = "json", method = { RequestMethod.GET })
public Object json(JavaType type) {
System.out.println(type.getName() + ":" + type.getValue());
type.setName("返回json数据");
return type;
}
/**
* 传入restful风格的参数
* http://localhost:8088/generateCode-platform/msok/web/restful
* 然后再header 里面加上参数 {"name":"返回json数据","value":"1这是initbinder"}
*/
@ResponseBody
@RequestMapping(value = "restful", method = { RequestMethod.POST })
public Object restful(@RequestBody JavaType type) {
System.out.println(type.getName() + ":" + type.getValue());
type.setName("restful返回");
return type;
}
<!--mvc:annotation-driven 会自动注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个实例 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
<!-- 返回的是fatjson 可以自动ajax传过去的值转换成对象,然后返回的值转换成json字符串-->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter" >
<property name="supportedMediaTypes" value="application/json;charset=UTF-8"/>
<!-- 解决json null问题 -->
<property name="features">
<array>
<!-- 是否输出值为null的字段,默认为false ,如果不加这个某个字段为空,那么json字符串里面就不会显示这个字段,比如{"name":"restful"} value不显示出来-->
<value>WriteMapNullValue</value>
<!-- 字符类型字段如果为null,输出为"",而非null 比如{"name":"restful","value":null}-->
<value>WriteNullStringAsEmpty</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 ,处理方法级别上的@RequestMapping注解,解决@ResponseBody ajax 乱码问题
配置了mvc:annotation-driven 就不需要这样配置了。
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="cacheSeconds" value="0" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
-->
handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解: @PathVariable;
B、处理request header部分的注解: @RequestHeader, @CookieValue;
C、处理request body部分的注解:@RequestParam, @RequestBody;
D、处理attribute类型是注解: @SessionAttributes, @ModelAttribute;
1、 @PathVariable
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。
示例代码:
[java] view plaincopyprint?
@Controller
@RequestMapping(“/owners/{ownerId}”)
public class RelativePathUriTemplateController {
@RequestMapping(“/pets/{petId}”)
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
上面代码把URI template 中变量 ownerId的值和petId的值,绑定到方法的参数上。若方法参数名称和需要绑定的uri template中变量名称不一致,需要在@PathVariable(“name”)指定uri template中的名称。
2、 @RequestHeader、@CookieValue
@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。
示例代码:
这是一个Request 的header部分:
Host localhost:8080
Accept text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language fr,en-gb;q=0.7,en;q=0.3
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
@RequestMapping(“/displayHeaderInfo.do”)
public void displayHeaderInfo(@RequestHeader(“Accept-Encoding”) String encoding,
@RequestHeader(“Keep-Alive”) long keepAlive) {
}
上面的代码,把request header部分的 Accept-Encoding的值,绑定到参数encoding上了, Keep-Alive header的值绑定到参数keepAlive上。
@CookieValue 可以把Request header中关于cookie的值绑定到方法的参数上。
例如有如下Cookie值:
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
参数绑定的代码:
@RequestMapping(“/displayHeaderInfo.do”)
public void displayHeaderInfo(@CookieValue(“JSESSIONID”) String cookie) {
}
即把JSESSIONID的值绑定到参数cookie上。
3、@RequestParam, @RequestBody
@RequestParam
A) 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String–> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;
B)用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST;
C) 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定;
示例代码:
@Controller
@RequestMapping(“/pets”)
@SessionAttributes(“pet”)
public class EditPetForm {
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam(“petId”) int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute(“pet”, pet);
return “petForm”;
}
@RequestBody
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap