SpringMVC 原理
前端控制器(DispatcherServlet) 通过 映射处理器(HandlerMaping)
找到 处理器(Handler) 和拦截器(HandlerInterceptor),
它们被封装到 HandlerExecutionChain.
前端控制器通过适配器(HandlerAdapter)调用 处理器(Handler),
处理器返回模型和视图(ModelAndView).
前端控制器把通过视图解析器(ViewResolver)解析出视图(View),
再把视图渲染, 返回给用户
DEMO
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
| <servlet>
<servlet-name>springmvc </servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<load-on-startup> 1 </load-on-startup>
<init-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
classpath:springmvc-servlet.xml
</param-value>
</init-param>
</servlet>
<filter>
<filter-name> CharactorEncoding</filter-name>
<filter-class> CharactorEncodingFilter </filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharactorEncoding </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name> springmvc </servlet-name>
<url-pattern> *.action </url-pattern>
</servlet-mapping>
|
springmvc-servlet.xml
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
|
<bean class="web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<bean class="SimpleControllerHandlerAdaptor">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean class="InternalResourceViewResolver"> </bean>
<bean id="hello_controller" name="/hello.action" class="HelloWorldController">
</bean>
|
1
2
3
4
5
6
7
8
9
10
11
| public class HelloWorldController implements Controller {
public ModelAndView handleRequest(reqeust, response) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "hello world");
modelAndView.setViewName("hello");
return modelAndView;
}
}
|
其他控制器
1
2
3
4
|
<bean name="/success.action" class="ParameterizableViewController">
<property name="viewName" value="success"></property>
</bean>
|
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
|
public class MyCommandController extends AbstractCommandController {
public MyCommandController() {
this.setCommandClass(Student.class);
}
@Override protected ModelAndView handler(request, response, object, errors) {
Student studuent = ojbect;
println(student);
return null;
}
@Override protected void initBnder(request, binder) {
binder.registerCustomerEditor(Date.class, new CustomerDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
}
public class MyFormContorller extends SimplerFormController{
public MyformController(){
this.setCommandClass(Student.class);
this.setCommandName("student");
}
@Override protected showForm(){}
@Override public void doSubmitAciton(Object command){}
}
|
参数控制器, 命令控制器, 表单控制器缺点:
传递参数格式固定为命令对象, 不灵活, controller中的方法固定,
不能任意定义控制方法
使用注解
1
2
3
4
5
6
7
| <context:component-scan base-package="action"></context:component-scan>
<bean class="RequestMappingHandlerMapping"></bean>
<bean class="RequestMappingHandlerAdaptor"></bean>
<bean class="InternalResourceViewResolver">...</bean>
|
1
2
3
4
5
6
7
8
9
10
11
| @Controller
public class HelloWorldController {
@RequestMapping(value="/hello")
public String helloworld(HttpServletRequest request, Student student, Model model){
model.addAttribute("message", "HelloWorld");
model.addAttribute("student", new Student("张三"));
return "hello";
}
}
|
URI
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
| @Controller
@ResourceeMapping("/user")
public class UserAction {
@RequestMapping("/userlist")
public String userlist(Model model) throws Exception {
return "user/userlist";
}
@RequestMapping("/useradd")
public String useradd(Request req, Response res,
Session session, Model model,
Map map, ModelMap modelMap,
) {
return "user/useradd";
}
@RequestMapping("/useraddsubmit", method=RequestMethod.POST)
public String useraddsubmit(Model model, User student) {
return "redirect:/user/userlist.action";
}
@RequestMapping(value="/useredit/{userid}", method={RequestMethod.GET, RequestMethod.POST})
@RequestMapping("/useredit/{userid:\\d+}")
public String useredit(@PathVariable String usesrid, Model model) {
}
@RequestMapping("/userdeletelist")
public String deletelist(String[] deleteid){
return "success";
}
@RequestMapping("/useraddlist")
public String useraddlist(Model model, User user,
@RequestPram(defaultValue="2", required=true, value="group" ) String groupid){
return "user/useraddlist";
}
@InitBinder
protected void initBnder(request, binder) {
binder.registerCustomerEditor(Date.class, new CustomerDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
}
|
实现json数据交互
@RequestBody
, 注解用户读取http请求的内容(字符串), 通过springMVC
提供的HttpMessageConverter 接口将读到的内容转换为 json, xml
等格式的数据并绑定到controller方法的参数上
@ResponseBody
, 该注解用于将Controller的方法返回的对象,
通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,
通过Response响应给客户端
Springmvc默认用 MappingJacksonHttpMessageConverter
对json数据进行转换,
需要加入jackson的包,jackson-core-asl.jar
, jackson-mapper-asl.jar
1
2
3
4
5
6
7
8
|
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
|
1
2
3
4
5
6
7
8
| @Controller
public class Body {
@RequstMapping("/")
public @ResponseBody Student requestjson(@RequestBody Student student) {
return student;
}
}
|
简化配置
1
2
3
|
<mvc:annotation-driven />
|
拦截器
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
| public class HandlerInterceptor1 implements HandlerInterceptor {
/**
* controller执行前调用此方法
* 返回true表示继续执行,返回false中止执行
* 这里可以加入登录校验、权限拦截等
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
return false;
}
/**
* controller执行后但未返回视图前调用此方法
* 这里可在返回用户前对模型数据进行加工处理,
* 比如这里加入公用信息以便页面显示
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
/**
* controller执行后且视图返回后调用此方法
* 这里可得到执行controller时的异常信息
* 这里可记录操作日志,资源清理等
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
}
}
|
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.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1" />
<ref bean="handlerInterceptor2" />
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1" />
<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2" />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**">
</mvc:mapping>
<bean class="HandlerIntercetpor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**">
</mvc:mapping>
<bean class="HandlerIntercetpor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
|
用户认证DEMO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| public class LoginInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if(request.getRequestURI().indexOf("login.action")>=0){
return true;
}
HttpSession session = request.getSession();
if(session.getAttribute("user")!=null){
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
}
|