SpringMVC是一个基于模型(M)-视图(V)-控制器(C)的的Web框架。
MVC模式使应用程序的不同方面(输入逻辑,业务逻辑 和 UI逻辑)分离,同时提供这些元素之间的松耦合。
Spring Web模型 - 视图 - 控制器(MVC)框架是围绕DispatcherServlet设计的,它处理所有的HTTP请求和响应。
中央前端控制器(是一个servlet -- DispatcherServlet):它负责每个请求到合适的处理程序。
1、中央前端控制器DispatcherServlet(不需要程序员开发) 作用:接收请求,相应结果。相当于转发器,中央处理器。 2、处理器映射器HandlerMapping(不需要程序员开发) 作用:根据请求的url查找Controller(也可称为Handler) 3、处理器适配器HandlerAdapter(不需要程序员开发) 作用:按照特定规则(HandlerAdapter要求的规则)去执行Controller 注意:编写Controller时按照HandlerAdapter的要求做,这样适配器才可以正确执行Controller 4、处理器Controller(需要程序员开发) 作用:实现具体的业务逻辑 5、视图解析器ViewResolver(不需要程序员开发) 作用:进行视图解析,根据逻辑视图名解析成真正的视图(view) 6、视图View(需要程序员开发) View是一个接口,实现类支持不同的view类型。
图片来源:https://www.yiibai.com/spring_mvc/spring-mvc-tutorial-for-beginners.html
在Controller中可以使用 HttpServletRequest, HttpServletResponse来获取http请求和返回http响应。
@Controller
public class HelloWorldController {
@RequestMapping("/hello")
public String requestResponseExample(HttpServletRequest request,
HttpServletResponse reponses, Model model) {
// Todo something here
return "helloworld";
}
}
使用前缀 "redirect:" ,该方法返回字符串,可以重定向到另一页面。
@Controller
public class RedirectController {
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String authorInfo(Model model) {
// Do somethong here
return "redirect:/redirect_newpage";
}
}
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestParam 注解将请求参数绑定到控制器方法参数。
@Controller
public class RequestParamController {
@RequestMapping("/user")
public String userInfo(Model model,
@RequestParam(value = "name", defaultValue = "Guest") String name) {
if("admin".equals(name)) {
model.addAttribute("email", "admin@yiibai.com");
} else{
model.addAttribute("email", "Not set");
}
return "userInfo";
}
}
userInfo.jsp如下:
<html>
<body>
<h2>${name}</h2>
Email: ${email}
</body>
</html>
现在在浏览器地址栏输入:http://localhost:8080/HelloSpringMVC/user?name=admin
页面显示:email: admin@yiibai.com
@PathVariable注释将一个方法参数绑定到一个URI模板变量的值。
@RequestMapping("/web/fe/{sitePrefix}/{language}/document/{id}/{naturalText}")
public String documentView(Model model,
@PathVariable(value = "sitePrefix") String sitePrefix,
@PathVariable(value = "language") String language,
@PathVariable(value = "id") Long id,
@PathVariable(value = "naturalText") String naturalText) {
model.addAttribute("sitePrefix", sitePrefix);
model.addAttribute("language", language);
model.addAttribute("id", id);
model.addAttribute("naturalText", naturalText);
}
return "documentView";
}
如果使用 @ResponseBody 注释到方法, spring 将尝试转换它的返回值,并自动写入到HTTP响应。在这种情况下,并不需要一个特定的视图。
注:返回值不一定是字符串类型。
@Controller
public class ResponseBodyExample1Controller {
// Simple example, method returns String.
@RequestMapping(value = "/saveResult")
@ResponseBody
publicString authorInfo(Model model) {
return "saved";
}
}
@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容。一般情况下来说常用其来处理application/json类型。
例如页面发送来一个ajax请求:
$.ajax({
url:"/login",
type:"POST",
data:'{"userName":"admin","pwd","admin123"}',
content-type:"application/json charset=utf-8",
success:function(data){
alert("request success ! ");
}
});
后台接收数据可以采用@requestBody注解:
@requestMapping("/login")
public void login(@requestBody String userName,@requestBody String pwd){
System.out.println(userName+" :"+pwd);
}
如果我有一个User类,拥有如下字段:
那么上述参数可以改为以下形式:@requestBody User user 。需要注意的是,JSON字符串中的key必须对应user中的属性名。
类ControllerClassNameHandlerMapping
是基于约定的处理程序映射类,它将URL请求映射到配置中提到的控制器的名称。这个类接收控制器名称并将其转换为带有前导“/”的小写形式。 例如HelloController映射到URL: ”/hello*”。
<beans>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<bean class="com.yiibai.springmvc.HelloController" />
<bean class="com.yiibai.springmvc.WelcomeController"/>
</beans>
使用上面的配置,URI:
/helloWorld.html
或 /hello{任何字母}.html
,DispatcherServlet
将请求转发到HelloController
类。/welcome.html
,DispatcherServlet
会将请求转发给WelcomeController
类。/welcome1.html
,DispatcherServlet
将不会找到任何控制器,服务器将抛出404
状态错误。SimpleUrlHandlerMapping
类分别显式地将URL
映射到相应的控制器上。
<beans>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/welcome.html">welcomeController</prop>
<prop key="/helloWorld.html">helloController</prop>
</props>
</property>
</bean>
<bean id="helloController" class="com.yiibai.springmvc.HelloController" />
<bean id="welcomeController" class="com.yiibai.springmvc.WelcomeController"/>
</beans>
使用上面的配置,如果URI:
/helloWorld.html
请求,DispatcherServlet
将请求转发到HelloController
类。/welcome.html
,DispatcherServlet
会将请求转发给WelcomeController
类。MultiActionController
类用于在单个控制器中分别映射多个URL到对应的方法。
public class UserController extends MultiActionController{
public ModelAndView home(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("home");
model.addObject("message", "Home");
return model;
}
public ModelAndView add(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("user");
model.addObject("message", "Add");
return model;
}
public ModelAndView remove(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("user");
model.addObject("message", "Remove");
return model;
}
}
URL映射配置文件如下:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/home.html" class="com.yiibai.springmvc.UserController" />
<bean name="/user/*.html" class="com.yiibai.springmvc.UserController" />
使用上面的配置,如果URI:
/home.html
请求,DispatcherServlet
将请求转发到UserController
类的 home()
方法。user/add.html
,DispatcherServlet
将请求转发到UserController
类的 add()
方法。user/remove.html
,DispatcherServlet
将请求转发到UserController
类的 remove()
方法。URL映射配置文件如下:
<bean class="com.yiibai.springmvc.UserController">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/user/home.html">home</prop>
<prop key="/user/add.html">add</prop>
<prop key="/user/update.html">update</prop>
</props>
</property>
</bean>
</property>
</bean>
使用上面的配置,如果URI:
/user/home.html
请求,DispatcherServlet
将请求转发到UserController
类的 home()
方法。user/add.html
,DispatcherServlet
将请求转发到UserController
类的 add()
方法。user/remove.html
,DispatcherServlet
将请求转发到UserController
类的 remove()
方法。URL映射配置文件如下:
<bean class="com.yiibai.springmvc.UserController">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="action"/>
</bean>
</property>
</bean>
使用上面的配置,如果URI:
/user/*.html?action=home
请求,DispatcherServlet
将请求转发到UserController
类的 home()
方法。/user/*.html?action=add
,DispatcherServlet
将请求转发到UserController
类的 add()
方法。/user/*.html?action=remove
,DispatcherServlet
将请求转发到UserController
类的 remove()
方法。URL映射配置文件如下:
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
index.html=userController
</value>
</property>
</bean>
<bean id="userController" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName" value="index"/>
</bean>
使用上面的配置,如果URI:
/index.html
请求,DispatcherServlet
会将请求转发到UserController
控制器,并将viewName
设置为index.jsp
。InternalResourceViewResolver
用于将提供的URI解析为实际URI。
@Controller
@RequestMapping("/hello")
public class HelloController{
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Spring MVC Framework 映射网页与请求示例!");
return "hello";
}
}
URL映射配置文件如下:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
使用上面的配置,如果URI
:
/hello
请求,DispatcherServlet
会将请求转发到prefix+ view-name + suffix = /WEB-INF/jsp/hello.jsp
。XmlViewResolver
用于在xml
文件中定义的视图bean
来解析视图名称。
XmlViewResolver-servlet.xml 配置如下所示 -
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location">
<value>/WEB-INF/views.xml</value>
</property>
</bean>
views.xml 配置如下所示 -
<bean id="hello"
class="org.springframework.web.servlet.view.JstlView">
<property name="url" value="/WEB-INF/jsp/hello.jsp" />
</bean>
例如,使用上面的配置,如果URI
:
/hello
请求,DispatcherServlet
会将请求转发到由view.xml
中定义的hello
对应的 hello.jsp
。ResourceBundleViewResolver
使用属性文件中定义的视图bean
来解析视图名称。
ResourceBundleViewResolver-servlet.xml 配置如下所示 -
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views" />
</bean>
这里basename
是指携带视图的资源束的名称。资源束的默认名称是views.properties
,可以使用basename
属性重写(也就是将views
修改为其它名称,对应的views.properties
文件名称也要修改)。
views.properties 配置如下所示 -
hello.(class)=org.springframework.web.servlet.view.JstlView
hello.url=/WEB-INF/jsp/hello.jsp
例如,使用上面的配置,如果URI
:
/hello
请求,DispatcherServlet
会将请求转发到由views.properties
中定义的hello
对应的 hello.jsp
。hello
”是要匹配的视图名称。class
指定视图类型,url
是视图的位置。MultipleResolver-servlet.xml 配置如下所示 -
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views" />
<property name="order" value="0" />
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="1" />
</bean>
这里order
属性定义了视图解析器的排序。0
作为第一解析器,1
作为下一解析器,等等。
views.properties 配置如下所示 -
hello.(class)=org.springframework.web.servlet.view.JstlView
hello.url=/WEB-INF/jsp/hello.jsp
例如,使用上面的配置,如果URI
:
/hello
请求,DispatcherServlet
会将请求转发到由views.properties
中定义的hello
对应的 hello.jsp
。hello
”是要匹配的视图名称。class
指定视图类型,url
是视图的位置。