SpringMvc的请求过程
【note:】
1、客户端request请求发起,请求到DispatcherServlet,DispatcherServlet其实就是一个控制器Controller.它会去”xxx-servlet.xml“配置文件中找到一个已经配置好的HandlerMapping的对应的”beanname“,然后通过它来找到请求url具体应该交给那个”Controller“去处理。
2、到了具体的”Controller“中,它通过与”Service“、”JavaBean“等完成交互,得到某一个值,然后返回一个”ModelAndView“视图。
3、返回的视图,通过配置的ViewResolver来找到它对应的具体的返回视图,以及它视图的返回形式。
4、最后返回具体的视图”View“展示到客户端浏览器上。
DispatcherServlet:package org.springframework.web.servlet;
HandlerMapping:org.springframework.web.servlet
【note:】
1、(注意是servlet下的)
2、”AbstractHandlerMapping”它实现了”HandlerMapping“接口,且”AbstractDetectingUrlHandlerMapping“继承了”AbstractHandlerMapping“,然后对于”AbstractDetectingUrlHandlerMapping“有三个重要的继承
”DefaultAnnotationHandlerMapping“:用的比较多的通过spring注解的方式来实现映射关系、
”BeanNameUrlHandlerMapping“:传统的通过”beanname“来配置HandlerMapping实现映射关系、
”AbstractControllerUrlHandlerMapping“
环境搭建
- 新建javaWeb项目,导入Springjar包和apache下的commons-loggin的jar包:
commons-logging.jar
spring-aop-4.1.1.RELEASE.jar
spring-aspects-4.1.1.RELEASE.jar
spring-beans-4.1.1.RELEASE.jar
spring-context-4.1.1.RELEASE.jar
spring-context-support-4.1.1.RELEASE.jar
spring-core-4.1.1.RELEASE.jar
spring-expression-4.1.1.RELEASE.jar
spring-instrument-4.1.1.RELEASE.jar
spring-instrument-tomcat-4.1.1.RELEASE.jar
spring-jdbc-4.1.1.RELEASE.jar
spring-jms-4.1.1.RELEASE.jar
spring-messaging-4.1.1.RELEASE.jar
spring-orm-4.1.1.RELEASE.jar
spring-oxm-4.1.1.RELEASE.jar
spring-test-4.1.1.RELEASE.jar
spring-tx-4.1.1.RELEASE.jar
spring-web-4.1.1.RELEASE.jar
spring-webmvc-4.1.1.RELEASE.jar
spring-webmvc-portlet-4.1.1.RELEASE.jar
spring-websocket-4.1.1.RELEASE.jar - 在”web.xml“中配置”DispatcherServlet“
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 设置在项目启动的时候就让它跟随启动 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!-- 所有的页面只要访问url,都会被servlet捕获,捕获之后就会进入到springmvc的处理 -->
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
【note:】
这里设置了”servlet-name“为”hello“,所以要创建一个对应的”hello-servlet.xml“,这里文件起名必须跟配置里设置的”servlet-name“一致。
4. 创建对应的spring的配置文件”hello-servlet.xml“
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean name="/welcome" class="com.xing.controller.WelcomeController"></bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
【note:】
1、通过设置”beanname“来完成映射关系。
2、配置相应的视图解析器”org.springframework.web.servlet.view.InternalResourceViewResolver“。
InternalResourceViewResolver:类中有两个属性,prefix:前缀,suffix:后缀。也就是说当对应的controller返回一个ModelAndView时,他会在已经配置好的”/WEB-INF/jsp/“这个路径下去找一个“ModelAndView返回的name“+”.jsp“这个具体的视图。
6. 创建上述步骤中配置的”class“对应的Controller(创建的Controller需要继承”AbstractController“)
package com.xing.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
/**
* Created with IntelliJ IDEA
* Created By 【星】
* Date: 2016/8/9
* Time: 18:05
*/
public class WelcomeController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
System.out.println("welcome");
//return 返回的是我们具体要对应的视图
return new ModelAndView("welcome");
}
}
- 在”/WEB-INF/jsp“下创建对应的视图文件(这里创建的视图文件的name根据Controller返回的结果来定)
<%--
Created by IntelliJ IDEA.
User: 【星】
Date: 2016/8/9
Time: 18:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>
启动”tomcat“访问地址:”http://localhost:8080/xing-spring-stu01/welcome“,如果浏览器中出现”Welcome“则说明成功了。
【note:】整个过程:
url请求:”http://localhost:8080/xing-spring-stu01/welcome“ 被”DispatcherServlet“拦截;
–>找到了beanname为”/welcome“的HandlerMapping;
–>就找到了对应的”WelcomeController.java“这个类,–>在该类中找到了”handleRequestInternal“方法;
–>在这个方法中处理之后,返回了”welcome“视图,这个是通过”InternalResourceViewResolver“去解析这个视图
–>根据解析器的设置,找到对应的welcome.jsp
基于Annotation的配置
1、打开Annotation:在对应的xxx-servlet.xml配置文件中打开:
<!--打开annotation-->
<context:component-scan base-package="com.xing.controller" />
<mvc:annotation-driven />
2、创建对应的”HelloController.java“
package com.xing.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Created with IntelliJ IDEA
* Created By 【星】
* Date: 2016/8/10
* Time: 15:22
*/
@Controller
public class HelloController {
@RequestMapping({"/hello","/hello1"})
public String hello(){
System.out.println("Hello");
return "hello" ;
}
}
3、创建好”hello.jsp“
@RequestMapping:支持多个映射路径指向同一个controller。
访问:”http://localhost:8080/xing-spring-stu01/hello“或者”http://localhost:8080/xing-spring-stu01/hello1“都可以。
传值到Controller
例子:在方法中用@RequestParam
@RequestMapping({"/sayHello1"})
public String sayHello1(@RequestParam("name") String name){
System.out.println("name=="+name);
return "hello" ;
}
测试:http://localhost:8080/xing-spring-stu01/sayHello1?name=ok
后台:成功获取”ok“
但是用了@RequestParam之后如果此时请求的时候没有传值的话就会抛出请求出错的异常。是因为用了@RequestParam,它会认为我们传递的参数也是请求url的一部分
解决上面这个问题,我们直接去掉@RequestParam,直接用参数传就可以了,如果参数确认是必不可少的可以用@RequestParam
请求的时候直接用函数的参数
@RequestMapping({"/sayHello2"})
public String sayHello2(String name){
System.out.println("name=="+name);
return "hello" ;
}
从Controller把值传给视图
1、Controller的方法中用使用Map集合
@RequestMapping({"/sayHello3"})
public String sayHello3(String name,Map<String,String> context){
System.out.println("name=="+name);
context.put("name",name) ;
return "hello" ;
}
2、Controller的方法中用Model,用它提供的addAttribute()方法来传值
@RequestMapping({"/sayHello4"})
public String sayHello4(String name,Model model){
System.out.println("name=="+name);
model.addAttribute("name",name) ;
return "hello" ;
}
model.addAttribute(Object) ;它还可以传递一个对象