SpringMVC
MVC
什么是mvc?
-
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
-
是将业务逻辑、数据、显示分离的方法来组织代码。
-
MVC主要作用是降低了视图与业务逻辑间的双向耦合。
-
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
Model(模型)
:数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或 JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层 (行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图)
:负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
Controller(控制器)
:接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型 数据返回给视图,由视图负责展示。 也就是说控制器做了个调度员的工作。
最典型的MVC就是JSP + servlet + javabean的模式。
- 用户发请求
- Servlet接收请求数据,并调用对应的业务逻辑方法
- 业务处理完毕,返回更新后的数据给servlet
- servlet转向到JSP,由JSP来渲染页面
- 响应给前端更新后的页面
职责分析:
controller:控制器
- 取得表单数据
- 调用业务逻辑
- 转向指定的页面
Model:模型
1. 业务逻辑
2. 保存数据的状态
View:视图
显示页面
Servlet回顾
- 导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
- 编写一个类,继承了HttpServlet,负责处理业务逻辑
public class ServletTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
HttpSession session = req.getSession();
if (method.equals("add")){
session.setAttribute("add","我是add");
}
if (method.equals("delete")){
session.setAttribute("add","我是delete");
}
req.getRequestDispatcher("/jsp/hello.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
编写web.xml文件,将servlet注册
<?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"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.nanda.ServletTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
-
编写一个jsp,将传入的代码显示
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${add}
</body>
</html>
MVC框架要做哪些事情
-
将url映射到java类或java类的方法
-
封装用户提交的数据
-
处理请求–调用相关的业务处理–封装响应数据
-
将响应的数据进行渲染 . jsp / html 等表示层数据
说明:
常见的服务器端MVC框架有:Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;
常见前端 MVC框架:vue、angularjs、react、backbone;
由MVC演化出了另外一些模式如:MVP、MVVM 等 等…
SpringMVC
概述
官方文档:springmvc官方文档
SpringMVC的优点:
- 轻量级,简单易学
- 高效 , 基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简洁灵活
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。
DispatcherServlet
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的 用户可以采用基于注解形式进行开发,十分简洁;
Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功 能,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)。
SpringMVC的执行原理
工作原理图:
工作流程:
- 客户端(浏览器)发送请求,直接请求到 DispatcherServlet 。
- DispatcherServlet 根据请求信息调⽤ HandlerMapping ,解析请求对应的 Handler 。
- 解析到对应的 Handler (也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。
- HandlerAdapter 会根据 Handler 来调⽤真正的处理器开处理请求,并处理相应的业务逻辑。
- 处理器处理完业务后,会返回⼀个 ModelAndView 对象, Model 是返回的数据对象, View 是 个逻辑上的 View 。
- ViewResolver 会根据逻辑 View 查找实际的 View 。
- DispaterServlet 把返回的 Model 传给 View (视图渲染)
-
- 把 View 返回给请求者(浏览器)
SpringMVC简易实现
bean配置实现SpringMVC
- 导入依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 配置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_4_0.xsd"
version="4.0">
<!--1.注册DispatcherServlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:springmvc-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别-1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的请求;(不包括.jsp)-->
<!--/* 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
-
编写springmvc的核心配置文件
名字可以随便起,但是要和上面的
<init-param>
中的<param-value>
相同- 统一的spring文件的格式
- 添加处理器映射器
- 添加处理器适配器
- 添加视图解析器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--处理器映射器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <!--处理器适配器--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean> <!--视图解析器器:DispatcherServlet给他的ModelAndView--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!--前缀和后缀,在mybatis的trim中曾经有过类似的--> <property name="prefix" value="/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
-
编写Controller层,实现方式有二,一是实现Controller接口,二是注解;需要返回一个ModelAndView,装数据,封视图;
public class helloSpringMVC implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv=new ModelAndView();
String a="xml";
mv.addObject("msg",a);
mv.setViewName("hello");
return mv;
}
}
- 在springmvc核心配置文件中,将自己的类交给SpringIOC容器,注册bean
原因:处理器映射器是BeanNameUrlHandlerMapping,所以任然需要注册bean,后面注解就不用了
<!--Handler-->
<bean id="/hello" class="com.nanda.helloSpringMVC"></bean>
- 写要跳转的jsp页面,显示ModelandView存放的数据,以及我们的正常页面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
可能遇到的问题:访问出现404,排查步骤
- 查看控制台输出,看一下是不是缺少了什么jar包。
- 如果jar包存在,显示无法输出,就在IDEA的项目发布中,添加lib依赖!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dO7ZTYZZ-1610385495737)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210110204751104.png)]
- 重启Tomcat 即可解决!
注解实现SpringMVC
可选:Maven可能存在资源过滤的问题,我们将配置完善
出现原因可见:maven资源过滤问题
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
- 导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 配置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_4_0.xsd"
version="4.0">
<!--1.注册DispatcherServlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:springmvc-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别-1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的请求;(不包括.jsp)-->
<!--/* 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
/ 和 / 的区别:*
< url-pattern > / 不会匹配到.jsp, 只针对我们编写的请求; 即:.jsp 不会进入spring的 DispatcherServlet类 。
< url-pattern > /* 会匹配 *.jsp, 会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,导致找不到对应的 controller所以报404错。
- 编写springmvc的核心配置文件
- 让IOC的注解生效(context扫描包)
- 静态资源过滤 :HTML . JS . CSS . 图片 , 视频 …
- MVC的注解驱动(替代处理器映射器和处理器适配器的配置)
- 配置视图解析器
在resource目录下添加springmvc-servlet.xml配置文件,配置的形式与Spring容器配置基本类似, 为了支持基于注解的IOC,设置了自动扫描包的功能,具体配置信息如下:
<?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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 让IOC的注解生效(context扫描包)-->
<context:component-scan base-package="com.nanda.controller"></context:component-scan>
<!-- 让springmvc不处理静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- MVC的注解驱动(替代处理器映射器和处理器适配器的配置)
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器-->
<bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- 编写Controller层
@Controller
@RequestMapping("/h1")
public class testController {
@RequestMapping("/h2")
public String helloTest(Model model){
model.addAttribute("msg","monmon");
return "hello";
}
}
- @Controller是为了让Spring IOC容器初始化时自动扫描到;
- @RequestMapping是为了映射请求路径,这里因为类与方法上都有映射所以访问时应该 是/h1/h2;
- 方法中声明Model类型的参数是为了把Action中的数据带到视图中;
- 方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成/jsp/hello.jsp。
- 创建视图层
在web下创建名为jsp的文件夹,下面新建hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
小结
实现步骤其实非常的简单:
-
新建一个web项目
-
导入相关jar包
-
编写web.xml , 注册DispatcherServlet
-
编写springmvc配置文件
-
接下来就是去创建对应的控制类 , controller
-
最后完善前端视图和controller之间的对应
-
测试运行调试.
使用springMVC必须配置的三大件: 处理器映射器、处理器适配器、视图解析器
通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而 省去了大段的xml配置
Controller和RequestMapping和RestFul
控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
实现controller接口
Controller是一个接口,在org.springframework.web.servlet.mvc包下,接口中只有一个方法;
//实现该接口的类获得控制器功能
public interface Controller {
//处理请求且返回一个模型与视图对象
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse
var2) throws Exception;
}
说明:
- 实现接口Controller定义控制器是较老的办法
- 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比 较麻烦;
使用注解@Controller
- @Controller注解类型用于声明Spring类的实例是一个控制器(在讲IOC时还提到了另外3个注 解);
- Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="com.kuang.controller"/>
测试流程:
- 新建项目
- 配置web.xml文件(dispacherservlet和filter等)
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- 配置springmvc配置文件
<?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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.nanda"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 实现controller接口时,只用一个视图解析器,不去配处理器映射器和处理器适配器,也能运行-->
<!-- <bean id="/hello" class="com.nanda.controller.ImpleController"></bean>-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
-
编写controller文件(实现接口或者使用注解)
使用注解:
@Controller public class AnnoController { @RequestMapping("/h1") public String test1(Model model){ model.addAttribute("msg","xml"); return "hello"; } }
实现接口:
public class ImpleController implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("msg","xml"); modelAndView.setViewName("hello"); return modelAndView; } }
-
编写前端jsp接受信息,注意要对应视图解析器的前缀和后缀
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
- 如果报404错,记得检查依赖是否加入lib包下
RequestMapping
@RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。 用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@Controller
public class TestController {
@RequestMapping("/h1")
public String test(){
return "test";
}
}
@Controller
@RequestMapping("/admin")
public class TestController {
@RequestMapping("/h1")
public String test(){
return "test";
}
}
访问路径:http://localhost:8080 / 项目名 / h1
访问路径:http://localhost:8080 / 项目名 /admin/ h1
RestFul风格
概念
概念: Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制
**功能资源:**互联网所有的事物都可以被抽象为资源 资源操作:使用POST、DELETE、PUT、GET,使用 不同方法对资源进行操作。 分别对应 添加、 删除、修改、查询
使用RestFul操作资源 : **可以通过不同的请求方式来实现不同的效果!**例如:请求地址一样,但是功能 可以不同!
http://127.0.0.1/item查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item 删除,DELETE
测试:
- 新建一个类
- 在springmvc中可以使用
@PathVariable
注解,让方法参数的值对应绑定到一个URI模板变量上。
@Controller
public class RestFulTest {
//映射访问路径
@RequestMapping(value = "/h2/{msg}/{msg1}",method = RequestMethod.GET)
public String test1(@PathVariable String msg,@PathVariable int msg1, Model model) {
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", msg);
System.out.println(msg + " " + msg1);
//返回视图位置
return "hello";
}
}
使用路径变量的好处?
- 使路径变得更加简洁;
- 获得参数更加方便,框架会自动进行类型转换。
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/h2/a/1,则路径与方法不匹配,而不会是参数转换失败。
使用method属性指定请求类型
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
指定类型的方法有两种:
- 在@RequestMapping里加上method属性
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
- 使用对应请求类型的注解
@PostMapping("/hello")
方法级别的注解变体有如下几个: 组合注解
- @GetMapping = @RequestMapping(method =RequestMethod.GET)
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
小结: Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以 及 PATCH。
不同请求可以通过postman
(一个软件)来发送
所有的地址栏请求默认都会是 HTTP GET 类型的。
结果跳转方式
最初我们学到的结果跳转是ModelAndView
和Model
他们一个通过setviewname方法,一个返回字符串。会根据对应的结果通过视图解析器跳转到指定的页面
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
@Controller
public class RestFulTest {
@RequestMapping("/h2")
public String test1(Model model) {
return "hello";
}
}
ServletAPI
**继承关系:**DispatcherServlet—>FrameworkServlet---->HttpServletBean—>HttpServlet
既然DispatcherServlet继承于HttpServlet,那么我们就能通过HttpServletRequest和HttpServletResponse去完成对应的结果跳转功能。
通过设置ServletAPI , 不需要视图解析器 !
- 通过HttpServletResponse进行输出
- 通过HttpServletResponse实现重定向
- 通过HttpServletResponse实现转发
@Controller
public class ServletTest {
@RequestMapping("/result/t1")
public void test1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.getWriter().println("xml是猪");
}
@RequestMapping("/result/t2")
public void test2(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.sendRedirect("/springmvcTest_04_ControllerAndRestful_war_exploded/index.jsp");
}
@RequestMapping("/result/t3")
public void test3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("msg","xml是猪");
req.getRequestDispatcher("/jsp/hello.jsp").forward(req,resp);
}
}
springmvc
区别在于有无视图解析器
@Controller
public class ForwardAndSendirect {
//下面三个注释掉视图解析器仍然有效
@RequestMapping("/fas/t1")
public String test1(){
return "/index.jsp";
}
@RequestMapping("/fas/t2")
public String test2(){
return "forward:/index.jsp";
}
@RequestMapping("/fas/t3")
public String test3(){
return "redirect:/index.jsp";
}
//下面两个是开着视图解析器,也都成功了,写着转发重定向的视图解析器不会解析
@RequestMapping("/fas/t4")
public String test4(){
return "forward:/index.jsp";
}
@RequestMapping("/fas/t5")
public String test5(){
return "redirect:/index.jsp";
}
}
数据接受处理
后端接受数据
提交的域名称和处理方法的参数名一致
提交数据 : http://localhost:8080/项目名称/h1?name=xx
@GetMapping("/h1")
public String test1(String name){
//接受前端用户传递的参数,判断参数的名字,假设名字直接写在方法上,可以直接使用
System.out.println(name);
return "hello";
}
提交的域名称和处理方法的参数名不一致
提交数据 : http://localhost:8080/项目名称/h1?username=xx
//RequestParam修饰后,原本错误的参数名不会报错,现在如果错误的参数名会报错
@GetMapping("/h2")
public String test2(@RequestParam("username") String name){
System.out.println(name);
return "hello";
}
提交的是一个对象
提交数据 : http://localhost:8080/项目名称/h1?name=xx&age=xx
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
@GetMapping("/h3")
public String test3(User user){
System.out.println(user);
return "hello";
}
前端接受数据
通过ModelAndView
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
通过ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}
通过Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
区别
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特 性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
乱码问题
在请求的过程中,用form表单提交后,在服务器段接受数据,我们会发现get请求:中文不乱码,post请求:中文乱码
原因:文本默认使用“text/plain;charset=ISO-8859-1”作为ContentType,导致中文乱码
解决方式:
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
*过滤路径要注意:/会匹配jsp页面,/不会
乱码问题,需要平时多注意,在尽可能能设置编码的地方,都设置为统一编码 UTF-8!
异常的处理
Spring的@ExceptionHandler可以用来统一处理方法抛出的异常,比如这样:
@ExceptionHandler()
public String handleExeption2(Exception ex) {
System.out.println("抛异常了:" + ex);
return "error";
}
里面也可以指定具体的类型
@ExceptionHandler({NumberFormatException.class,RuntimeException.class})
public String handleExeption(Exception ex) {
System.out.println("抛异常了:" + ex);
ex.printStackTrace();
String resultStr = "异常:NumberFormatException";
return resultStr;
}