Spring之Spring注解与数据绑定
本文主要总结Spring 常用注解,数据绑定,以及最为常见的接口请求的,Json数据下发,以及拦截器的常规使用。
Spring 常用注解
@Controller(控制器,注入服务)
Controller 注解是用于标记一个类上,使用它标记的类就是一个SpringMVC Controller对象。是一个控制器对象,这个类中方法就是具体的动作。一般是暴露出去的请求的定义。
@RequestMapping
是用来处理请求地址映射的注解,可以用于类火方法上。用于类上,标识类中的所有响应请求的方法是以该地址做为父路径。所以下面的地址是http://localhost:8080/parent.html/acdc
1
2
3
4
5
6
7
8
9
"parent.html") (value =
public class HelloController {
"acdc") (value =
public String hello(){
return "hello ,this is a ACDC demo";
}
}
@Service 服务(注入Dao)
Service注解是告诉Spring,当Spring要创建UserServiceImpl的实例时,bean的名字必须交”userService”,这样当Action需要使用UserServiceImpl的实例时,就可以由Spring创建好的userService,然后注入给Action。
@Repository (实现Dao)
其实就是Dao的实现。
@Component
把普通实例化到Spring容器中,相当于配置文件中的<bean id=”” class = “”/
@Autowired(依赖注入组件)
就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。getter看个人需求,如果私有属性需要对外提供的话,应当予以保留。
@ResponseBody
作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML。在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
@RestController
RestController注解相当于@Controller和@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,使用这个注解不能返回jsp和html页面,视图解析器无法解析。
@Resource
@Resource和@AutoWired比较类似,@Resource后面没有任何内容。两者的区别@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配。@Autowired是Spring的注解,@Resource是J2EE的注解,Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。
@JsonIgnoreProperties
将这个注解写在类上之后,就会忽略类中不存在的字段,可以满足当前的需要。
三种常规接口
返回的index,是返回jsp页面的名称
字符串参数来处理。请求地址(http://localhost:8080/home/index?homeId=4777)
1
2
3
4
5
6
7"/index", method = RequestMethod.GET) (value =
public String index(@RequestParam("homeId") Integer homeId, Model model) {
log.debug("This is a out put homeId = {}", homeId);
Home home = homeService.getHomeById(homeId);
model.addAttribute(home);
return "index";
}使用路径变量来处理。请求地址(http://localhost:8080/home/index2/5666)
1
2
3
4
5
6
7"/index2/{homeId}", method = RequestMethod.GET) (value =
public String index2(@PathVariable("homeId") Integer homeId, Map<String, Object> map) {
log.debug("This is a out put homeId = {}", homeId);
Home home = homeService.getHomeById(homeId);
map.put("home", home);
return "index";
}
使用HttpServletRequest处理。请求地址(http://localhost:8080/home/index3?homeId=333)
1
2
3
4
5
6
7"index3", method = RequestMethod.GET) (value =
public String index3(HttpServletRequest httpServletRequest) {
Integer homeId = Integer.valueOf(httpServletRequest.getParameter("homeId"));
Home home = homeService.getHomeById(homeId);
httpServletRequest.setAttribute("home", home);
return "index";
}
Binding
将请求中的字段按照名字匹配的原则,填入模型对象。:
新建的模型类需要与JSP里的界面文件进行名称匹配.
1
2
3
4
5
6public class Home {
int id;
String name;
String title;
String content;
}在views下新建一个index.jsp的View,通过EL表达式可以${home.title}来进行展示数据的绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>This is a Index Title</title>
<link rel="stylesheet" type="text/css" href="../statics/css/index.css">
</head>
<body>
<h2>Welcome to the fucking Spring world!</h2>
<ui>
<li>标题:${home.title}</li>
<li>id:${home.id}</li>
<li>正文:${home.content}</li>
<li>名称:${home.name}</li>
</ui>
</body>
</html>home变量即方式二里的map.put(“home”, home)或者方式三当中的使用HttpServletRequest的httpServletRequest.setAttribute(“home”, home);
其他: 如果要进行项目内的页面重定向,在返回的地方使用”redirect:” + 后面的地址;
文件上传
文件上传的概率其实相对来说比较简单,这里标记几个关键点。Demp用例上有单独的说明,使用MultipartFile来上传文件,表单需要加上enctype=”multipart/form-data”
1 | <form method="post" action="/home/upload" enctype="multipart/form-data"> |
1 | "/upload", method = RequestMethod.POST) (value = |
Spring与Json
一般步骤
pom.xml引入maven依赖。一般引入最高版本,去maven远程库看最高版本号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.7</version>
</dependency>配置dispacher-servlet.xml来处理接口返回的数据,主要是通过RequestMappingHandlerAdapter适配器来处理接口请求应该以什么返回等。
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<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<!-- 设置返回字符串编码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html; charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- json转换器 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html; charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
接口定义
1
2
3
4
5
6
7
8
9
10"/{id}", method = RequestMethod.GET) (value =
public Home getHomeInJson(@PathVariable Integer id) {
return homeService.getHomeById(id);
}
"/jsontype/{id}", method = RequestMethod.GET) (value =
public ResponseEntity<Home> getHomeInJson2(@PathVariable Integer id) {
Home home = homeService.getHomeById(id);
return new ResponseEntity<>(home, HttpStatus.OK);
}
拦截器与过滤器
作用场景
- 解决编码乱码问题
- 解决权限验证问题。
过滤器
过滤器的包在org.springframework.web.filter包中。具体的配置信息在web.xml当中,因为他的作用域在web服务器当中,所有请求都会经过过滤器进行操作。
请求都经过utf8编码
1
2
3
4
5
6
7
8
9
10
11
12
13<!-- 配置过滤器(设置为UTF-8) -->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
拦截器
实现HandlerInterceptor接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public class TestInterceptor implements HandlerInterceptor{
//object handler表示被拦截请求的目标
//返回true->请求被继续
//返回false->请求被终止
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
//可以通过ModelAndView来改变显示的视图,或者修改发往视图的方法
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// modelAndView.addObject("name","test");
// modelAndView.setViewName("/success.jsp");
}
//可以做资源销毁等操作
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}将拦截器注册进Spring MVC(dispatcher-servlet.xml)框架
1
2
3<mvc:interceptors>
<bean class="com.rocka.interceptor.TestInterceptor"></bean>
</mvc:interceptors>
- 拦截器的执行顺序为:preHandle() -> postHandle() -> afterCompletion()
多个拦截器的执行顺序为:
客户端request -> preHandle1() -> preHandle2() -> spring controller -> postHandle1() -> postHandle2() -> afterCompletion1() -> afterCompletion2() -> 客户端
区别
- 区别一过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大。
- 拦截器Interceptor依赖于框架容器,基于反射机制,只过滤请求
总结: 拦截器可以处理Web应用中请求的一些通用性问题,共性问题在拦截器处理,减少重复代码,利于维护