MVC模式
JSP+Servlet+JavaBean模式是最经典的MVC模式。
视图(view):负责格式化数据并把它们呈现给用户,eg:数据展示,数据验证,界面设计。 对应组件:jap或HTML文件。
控制器(controller):负责接受并转发请求。对请求进行处理后指派视图并响应结果发送给客户端。 对应组件:servlet.
模型(model):模型对象拥有最多的处理任务。主体部分,负责业务逻辑的处理和实现对数据的操作。对应组件 JavaBean(service层,DAO层,POJO层)
松耦合+高重用性+高可适用性
SpringMVC框架的体系结构
工作步骤:
1.客户端发出请求信息到Web应用服务器,如果请求路径与web.xml配置文件中定义的DispatcherServlet请求映射路径相匹配,那么,Web容器就会将该请求转交给DispatcherServlet处理。
2.DispatcherServlet到客户端请求后,根据请求的信息(包括URL,请求参数,Http方法等)找到处理请求的处理器Handler。
3.DispatcherServlet根据HandlerMapping的处理结果找到对应当前请求的Handler之后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter接口中共有一下三个方法:
1>supports()方法:判断是否可以使用某个Handler.
2>handle()方法:调用Handler处理业务。
3>getLastModified()方法:获取资源的最后修改时间。
4.在请求信息到达真正调用Handler的处理方法之前的这段时间内,SpringMVC框架还完成了很多工作,它会将请求信息以一定的方式转换并绑定到请求方法的入参中,对于入参的对象会进行数据转换,数据格式化及数据校验等。这些都做完之后,才真正调用Handler的处理方法,进行相应的业务逻辑处理。
5.处理器完成业务逻辑处理之后返回一个ModelAndView对象给DispatcherServlet,ModelAndView对象包含逻辑视图名和模型数据信息。
6.ModelAndView对象中包含的是“逻辑视图名”,而非真正的视图对象,DispatcherServlet会通过ViewResolver视图解析器将逻辑视图名解析为真正的视图对象View。当然负责数据展示的视图可以为JSP,XML , PDF , JSON等多种数据格式,Spring MVC可以灵活配置。
7.当得到真是的视图对象View后,DispatcherServlet会使用ModelAndView对象中的模型数据对View进行视图渲染。
8.客户端获得的响应消息可以是普通的HTML页面,也可以是一个XML或JSON等数据格式。
使用SpringMVC编写程序
使用springMVC编写的一定是web项目。
1.原生方法
步骤:
1.编写web.xml文件
<?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_4_0.xsd"
version="4.0">
<!-- SpringMVC的核心是一个Servlet,前端控制器-->
<!-- 定义了一个名为springMVC的Servlet,并指向DispatcherServlet。-->
<!-- DispatcherServlet是SpringMVC的核心-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springMVC配置文件-->
<!-- 在载入当前servlet时,使用init-param标签,加载springmvc-servlet.xml配置文件-->
<init-param>
<!-- contextConfigLocation为DispatcherServlet类父类中的属性,
用于加载配置文件的路径-->
<param-name>contextConfigLocation</param-name>
<!-- 给contextConfigLocation属性赋值路径-->
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 1 表示当前servlet会在系统启动时被载入-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- / 表示当前servlet拦截所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.编写核心配置文件信息
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--定义控制器,访问路径为/hello-->
<bean name="/hello" class="com.demo.controller.HelloController"/>
<!--视图-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3.编写Controlle包中的HelloController类
package com.demo.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
System.out.println("第一个SpringMVC框架搭建成功!");
return new ModelAndView("index");
}
}
4.运行
使运行的路径为http://localhost:80/项目名/hello,若控制台输出【第一个SpringMVC框架搭建成功!】为成功。
2.使用注解
步骤:
1.编写核心配置文件信息
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!--开启注解驱动-->
<mvc:annotation-driven/>
<!-- 注解扫描的包-->
<context:component-scan base-package="com.demo.controller"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 路径前缀-->
<property name="prefix" value="/WEB-INF/"/>
<!-- 路径后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
2.编写web.xml文件
<?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_4_0.xsd"
version="4.0">
<!-- SpringMVC的核心是一个Servlet,前端控制器-->
<!-- 定义了一个名为springMVC的Servlet,并指向DispatcherServlet。-->
<!-- DispatcherServlet是SpringMVC的核心-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springMVC配置文件-->
<!-- 在载入当前servlet时,使用init-param标签,加载springmvc-servlet.xml配置文件-->
<init-param>
<!-- contextConfigLocation为DispatcherServlet类父类中的属性,
用于加载配置文件的路径-->
<param-name>contextConfigLocation</param-name>
<!-- 给contextConfigLocation属性赋值路径-->
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 1 表示当前servlet会在系统启动时被载入-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- / 表示当前servlet拦截所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.在controller包层中编写helloController类
package com.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 控制器类,加上注解 @Controller
*/
@Controller
public class HelloController {
/**
* 具体方法,执行后可跳转页面, @RequestMapping注解声明路径
* @return
* @throws Exception
*/
@RequestMapping(value = "/hello")
public String hello() throws Exception{
// 打印
System.out.println("springmvc");
//跳转到hello页面
return "index";
}
}
4.运行
使运行的路径为http://localhost:80/项目名/hello,若控制台输出【第一个SpringMVC框架搭建成功!】为成功。
前后端数据交互
1,@RequestMapping注解
可用于控制器的类上。控制器的方法上。其映射的请求信息必须保证全局唯一。
package com.demo.controller;
import com.demo.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller//声明控制器
@RequestMapping("/account")//指定请求的路径名
public class AcountController {
//登录的跳转方法
@RequestMapping(value ="/login")
public String login(){
//在控制台打印
System.out.println("=====================================");
return "login";
}
//登录实现的跳转方法
@RequestMapping("/reLogin")
public ModelAndView reLogin(User user){
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("user",user);
modelAndView.setViewName("show2");
return modelAndView;
}
}
@RequestMapping注解中的method方法可以为接口设置访问类型,对应值是Spring定义的枚举RequestMethod。其所有类型有----GET,HEAD,POST,PUT,DELETE,OPTIONS,TRACE。
@RequestMapping(value ="/login",method = RequestMethod.GET)
public String login(){
System.out.println("=====================================");
//跳转页面
return "login";
}
@RequestMapping(value ="/login2",method = RequestMethod.POST)
public String login2(){
System.out.println("=====================================");
//跳转页面
return "login";
}
此外SpringMVC框架还提供了@GetMapping,@PostMapping等注解实现类似功能。
@GetMapping(value ="/login")
public String login(){
System.out.println("=====================================");
//跳转页面
return "login";
}
@PostMapping("/login2")
public String login2(){
System.out.println("=====================================");
//跳转页面
return "login";
}
上述代码中@GetMapping(value ="/login")等同于@RequestMapping(value ="/login",method = RequestMethod.GET),@GetMapping等注解是依赖于@RequestMapping注解实现的。
2,@RequestParam注解-----处理入参
只要在控制器接口方法中定义希望传入的参数,并在参数前添加此注解即可,
注意,页面传入的参数name要和接口种方法的参数名称相同。
/**
* 具体方法,执行后可跳转页面, @RequestMapping注解声明路径
* @RequestParam注解指定入参参数
* @return
* @throws Exception
*/
@RequestMapping(value = "/hello")
public ModelAndView hello(@RequestParam String name) throws Exception{
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("name",name);
modelAndView.setViewName("show");
//跳转到hello页面
return modelAndView;
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/hello" method="post">
请输入acount:<input type="text" name="name">
<input type="submit" value="提交">
</form>
</body>
</html>
@RequestParam注解提供的一些参数
参数 | 说明 |
---|---|
name | 同value |
value | 同name |
required | 是否必需, 默认为true, 表示请求中必须包含对应的参数名,若不存在,则抛出异常。 |
defaultValue | 为参数赋默认值 |
/**
* 具体方法,执行后可跳转页面, @RequestMapping注解声明路径
* @RequestParam注解指定入参参数 ,此时传入的参数名称必须为cname,且是必须传入。且默认值是小明
* @return
* @throws Exception
*/
@RequestMapping(value = "/hello")
public ModelAndView hello(@RequestParam(value = "cname",required = true,defaultValue = "小明") String name) throws Exception{
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("name",name);
//跳转到show页面
modelAndView.setViewName("show");
return modelAndView;
}
3,处理出参
1,使用ModelAndView对象
既包含视图信息,又包含模型数据信息。
@RequestMapping(value = "/hello")
public ModelAndView hello(@RequestParam String name) throws Exception{
//创建对象
ModelAndView modelAndView=new ModelAndView();
//添加模型数据
modelAndView.addObject("name",name);
//跳转到show页面
modelAndView.setViewName("show");
return modelAndView;
}
常用方法
方法 | 说明 |
---|---|
ModelAndView addObject(String attributeName, Object attributeValue) | attributeName为key值(可自定义),attributeValue为key对应的value。 |
ModelAndView addAllObjects ( Map<String, ?> modelMap) | 数据模型是一个Map对象,添加Map对象到Model中。 |
void setView(View view) | 指定一个视图对象 |
void setViewName(String viewName) | 指定一个逻辑视图名 |
2,使用Model对象
SpringMVC在调用方法前,会创建一个隐含的模型对象作为模型数据的存储容器,一般成为隐含模型。
若控制器接口的入参中包含model类型,SpringMVC会将隐含模型的引用传递给这些入参。
简单的说,在方法体内,开发者可以通过一个model类型的入参对象访问到模型中的所有数据,当然也可以 向模型中添加新的属性数据,**使用model对象完成参数传递的功能。**model对象也是一个Map类型的数据结 构。
@RequestMapping(value = "/hi")
public String hei(Model model, @RequestParam String name) throws Exception{
//添加模型数据 ---1
//此用法和ModelAndView的addObject方法一样
model.addAttribute("name",name);
//添加模型数据 ---2
//此方法没有指定model的key值,默认使用对象的类型作为key,且首字母小写
//如name的类型是String,那么key值则为string
model.addAttribute(name);
return "show";
}
jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--第一种取key为name--%>
<h1>名字为:${name}</h1>
<%--第二种取key为string--%>
<h1>名字为:${string}</h1>
</body>
</html>
3,使用Map对象
map类型入参,使用方法和model方法,大至相同
@RequestMapping(value = "/hi")
public String hi(Map<String,Object> map, @RequestParam String name) throws Exception{
//添加
map.put("name",name);
//跳转页面
return "show";
}
jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>名字为:${name}</h1>
</body>
</html>
4,使用注解
@SessionAttributes注解
此注解可以将模型中的属性存入HttpSession中,以便在多个请求之间共享该属性。
@ModelAttribute注解
若希望将入参的数据对象放入数据模型中去,就需要在相应入参前使用此注解。
5,使用某些作用域
HttpServletRequest , HttpServletResponse , HttpSession
@RequestMapping(value = "/hello")
public String hello(HttpRequest request,@RequestParam String name) throws Exception{
//添加数据
request.setAttribute("name",name);
return "index";
}
控制器之间的跳转
1,转发
forward
@RequestMapping(value = "/hi")
public String hi(Map<String,Object> map, @RequestParam String name) throws Exception{
//添加
map.put("name",name);
//转发到指定路径(控制器的指定路径)
return " forward:show";
}
2,重定向
redirect
@RequestMapping(value = "/hi")
public String hi(Map<String,Object> map, @RequestParam String name) throws Exception{
//添加
map.put("name",name);
//重定向到指定路径(控制器的指定路径)
return " redirect:show";
}