springmvc回顾笔记
特点
- 轻量级简单易学
- 高效,基于请求响应的MVC框架
- 与Spring兼容性好,无缝连接
- 约定优于配置
- 功能强大:Restful 数据验证 格式化 本地化 主题等
- 简洁灵活
Spring的web框架围绕DispatcherServlet[调度Servlet]设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始,使用Java5或者以上版本可以采用基于注解的controller声明方式
执行流程
官网的流程



- DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
- 我们假设请求的url为:http://localhost:8080/SpringMVC/hello
- 如上url拆成三个部分:
- http://localhost:8080/服务器域名
- SpringMVC部署在服务器上的web站点
- hello表示控制器
- 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器
- HandleMapping为处理器映射。DispatcherServlet调用HandleMapping,HandleMapping根据请求的url查找Handle。
- HandleExecution表示具体的Handle,注意的作用是根据url查找控制器。如上url被查找的控制器为hello
- HandleExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
- HandleAdapter 表示处理器适配器,按照特定的规则执行Handler
- Handler让具有的Controller执行
搭建
配置版
-
新建一个Moudle,添加web的支持

-
确定导入了SpringMVC的依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> </dependencies> -
配置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"> <!--配置Dispatcher:这个是SpringMVC的核心:请求分发器,前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatcherServlet要绑定SpringMVC的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> </servlet> <!-- / 匹配所有的请求(不包括.jsp)--> <!-- /* 匹配所有的请求(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> -
编写SringMVC的配置文件!名称:springmvc-servlet.xml:[servletname]-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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--处理器映射器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <!--处理器配置器--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> <!--视图解析器:模板引擎 Thymeleaf Freemacker...--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean id="/hello" class="com.hing.controller.HelloController"/> </beans> -
添加处理器
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> -
添加处理器适配器
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> -
添加视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> -
编写我们要做的操作业务Controller,要么实现Controller接口,要么添加注释;需要返回一个ModelAndView,装数据,封装视图;
package com.hing.controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //注意:这里我们先导入Controller接口 public class HelloController implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result="HelloSpringMVC"; mv.addObject("msg",result); //视图跳转 mv.setViewName("test"); return mv; } } -
将自己的类交给SpringIOC,注册bean
<!--handler--> <bean id="/hello" class="com.hing.controller.HelloController"/> -
要写跳转的jsp页面,显示ModelandView存放的数据,以及我们的正常页面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html> -
配置Tomcat启动测试!
可能遇到的问题:访问404,排查步骤
-
查看控制台输出,看是不是缺少什么jar
-
如果jar存在,显示无法输出,就要在IDEA的项目发布中,添加lib依赖!

-
重启Tomcat解决问题
注解版
-
新建Module,添加web支持!建立包结构com.hing.controller
-
由于Maven可能存在资源过滤的问题,我们将配置完善
<build> <resources> <resource> <directory>src/main/java</directory><!--所在目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <!-- 扫描resources下的.xml和.properties配置文件 --> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>false</filtering> </resource> </resources> </build> -
在pom.xml文件引入相关的依赖:主要有Spring框架核心库、Spring MVC、servlet、JSTL等。我们在父依赖中已经导入了!
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.6</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> -
配置web.xml
注意点:
- 注意web.xml版本问题,要最新版本
- 注册DispatcherServlet
- 关联SpringMvc的配置文件
- 启动级别为1
- 映射路径为/[不要用/*,会404]
<?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"> <!--配置Dispatcher:这个是SpringMVC的核心:请求分发器,前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatcherServlet要绑定SpringMVC的配置文件--> <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> <!-- / 匹配所有的请求(不包括.jsp)--> <!-- /* 匹配所有的请求(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> -
添加Spring MVC配置文件
-
让IOC注解生效
-
静态资源过滤: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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvn="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://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:component-scan base-package="com.hing.controller"/> <!--让Spring MVC不处理静态的资源 .css .js .html .mp3 .mp4--> <mvn:default-servlet-handler/> <!--支持MVC注解驱动 在spring中一般采用@RequestMapping来完成映射关系 要想使@RequestMapping注解生效 必须向上下文中注册DefaultAnnotationHandleMapping 和一个AnnotationMethodHandleAdapter实例 这两个实例分别在类级别和方法级别处理 而annotation-driven配置帮助我们自动完成上述两个实例的注入--> <mvn:annotation-driven/> <!--视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans>在视图解析器中我们把所有的视图存放在/WEB-INF/目录下,这样可以保证视图的安全,因为这个目录下的文件,客户端不能直接访问
-
-
创建Controller
package com.hing.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/HelloController") public class HelloController { //真实访问地址:项目名/HelloController/hello @RequestMapping("/hello") public String hello(Model model){ //向模型添加属性msg的值,可以在jsp页面中取出并渲染 model.addAttribute("msg","Hello,SpringMVCAnnotation!"); //WEB-INF/jsp/hello.jsp return "hello"; } }- @Controller是为了让SpringIOC容器初始化时自动扫描到
- @RequestMapping是为了映射请求的路径,这里因为类与方法上都有映射所以访问时应该是/HelloController/hello
- 方法中声明的Model类型的参数是为了把action中的数据带到视图中
- 方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp
-
创建视图层
在WEB-INF/jsp目录下创建hello.jsp,视图可以直接取出并展示从Controller带回来的信息,可以通过EL表示取出的Model中存放的值,或者对象
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html> -
配置Tomcat运行
小结
实现的步骤:
- 新建一个web的项目
- 导入相关jar包
- 编写web.xml,注册DispatcherServlet
- 编写springmvc配置文件
- 接下来就是创建对应的控制器,controller
- 最后完善前端视图和controller之间的对应
- 测试运行测试
使用SpringMVC必须配置的三大件:
处理器映射器、处理器适配器、视图解析器
通常,我们只需要手动的配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,省去了大段的xml配置
RestFul风格
概念
RestFul就是一个资源定位及资源操作的风格。不是标准而是协议,只是一种风格。基于这个风格设计的软件更简洁,更有层次,更易于实现缓存机制
功能
- 资源:互联网所有的事物都可以被抽象为资源
- 资源操作:使用POST、DELETE、PUT、GET,使用不同的方法对资源进行操作。
- 分别对应的添加、删除、修改、查询
传统方式操作资源
通过不同的参数来实现不同的效果!方法单一,post和get
- http://127.0.0.1/item/queryItem.action?id=1 查询,GET
- http://127.0.0.1/item/saveItem.action 新增,POST
- http://127.0.0.1/item/updateItem.action 更新,POST
- http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或者POST
使用RESTful操作资源
可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
- http://127.0.0.1/item/1查询,GET
- http://127.0.0.1/item新增,POST
- http://127.0.0.1/item更新,PUT
- http://127.0.0.1/item/1 删除,DELETE
重定向和转发
无视图解析器的情况:(需要把视图解析器注释掉)
package com.hing.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ModelTestController {
@RequestMapping("/m1/t1")
public String test1(Model model){
//转发
model.addAttribute("msg","ModelTest1");
return "/WEB-INF/jsp/test.jsp";
}
@RequestMapping("/m1/t2")
public String test2(Model model){
//转发
model.addAttribute("msg","ModelTest2");
return "forward:/WEB-INF/jsp/test.jsp";
}
@RequestMapping("/m1/t3")
public String test3(Model model){
//重定向
model.addAttribute("msg","ModelTest3");
return "redirect:/index.jsp";
}
}
有视图解析器的情况:重定向不需要视图解析器,本质上就是重新请求一个新的地址,注意路径问题
package com.hing.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ModelTestController {
@RequestMapping("/m1/t1")
public String test1(Model model){
//转发
model.addAttribute("msg","ModelTest1");
return "test";
}
@RequestMapping("/m1/t3")
public String test3(Model model){
//重定向
model.addAttribute("msg","ModelTest3");
return "redirect:/index.jsp";
}
}
乱码
Get Post乱码
web.xml配置SpringMVC的默认过滤器
<!--2. 配置SpringMVC的乱码过滤-->
<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>
Json乱码
Jackson ,spring的配置文件:springmvc-servlet.xml中配置
<!--JSON乱码问题配置-->
<mvn:annotation-driven>
<mvn:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvn:message-converters>
</mvn:annotation-driven>
SSM
-
最终文件结构

-
新建Maven项目,添加web支持

-
pom.xml,导入相关的pom依赖
<dependencies> <!--依赖:Junit 、数据库驱动 、连接池 、servlet 、jsp 、mybatis 、mybatis-spring 、spring --> <!--Junit--> <dependency> <groupId>juint</groupId> <artifactId>juint</artifactId> </dependency> <!--数据库驱动--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.5</version> </dependency> <!--数据库连接池 c3p0 dbcp--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!--Servlet-JSP--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> <!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.6</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> </dependencies> -
pom.xml,maven资源过滤设置
<!--静态资源导出--> <build> <resources> <resource> <directory>src/main/java</directory><!--所在目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <!-- 扫描resources下的.xml和.properties配置文件 --> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>false</filtering> </resource> </resources> </build> -
建立基本结构和配置框架
-
com.hing.pojo
-
com.hing.dao
-
com.hing.service
-
com.hing.controller
-
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration> -
applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
-
Mybatis层编写
-
数据库配置文件database.properties
jdbc.driver=org.postgresql.Driver jdbc.url=jdbc:postgresql://172.22.24.199:5432/ihcc-cloud?useSSL=false&serverTimezone=GMT%2B8 jdbc.username=postgres jdbc.password=Ab@123456 -
IDEA关联数据库
-
编写Mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--配置数据源 交给spring去做--> <typeAliases> <package name="com.hing.pojo"/> </typeAliases> <mappers> <mapper class="com.hing.dao.BookMapper"/> </mappers> </configuration> -
编写数据库的实体类 com.hing.pojo.Books,使用Lombok插件
package com.hing.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Books { private String id; private String a; private String b; private String c; } -
编写Dao层Mapper接口
package com.hing.dao; import com.hing.pojo.Books; public interface BookMapper { //新增一本书 int addBook(Books books); //查询全部 List<Books> queryAllBook(); ... } -
编写接口对应的Mapper.xml文件。需要导入Mybatis的包
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hing.dao.BookMapper"> <insert id="addBook" parameterType="Books"> insert into adapter_info_test(id,a,b,c) values (#{id},#{a},#{b},#{c}) </insert> <select id="queryAllBook" resultType="Books"> select * from adapter_info_test </select> ... </mapper> -
编写service层的接口和实现类
接口:
package com.hing.service; import com.hing.pojo.Books; public interface BookService { //新增一本书 int addBook(Books books); //查询全部 List<Books> queryAllBook(); ... }实现类:
package com.hing.service; import com.hing.dao.BookMapper; import com.hing.pojo.Books; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { @Autowired private BookMapper bookMapper; public int addBook(Books books) { return bookMapper.addBook(books); } public List<Books> queryAllBook(){return bookMapper.queryAllBook();} ... }
Spring层
-
配置Spring整合Mybatis,数据源使用的c3p0连接池
-
编写Spring整合Mybatis的相关配置文件:spring-dao.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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--1 关联数据库配置文件--> <context:property-placeholder location="classpath:database.properties"/> <!--2 连接池 dbcp:半自动化操作,不能自动连接 c3p0:自导哪个好操作(自动化的加载配置文件,并且可以自动的设置到对象中) driud: hikari: --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!--c3p0连接池的私有属性--> <property name="maxPoolSize" value="30"/> <property name="minPoolSize" value="10"/> <!--关闭连接后不自动commit--> <property name="autoCommitOnClose" value="false"/> <!--连接超时时间--> <property name="checkoutTimeout" value="10000"/> <!--连接失败重试次数--> <property name="acquireRetryAttempts" value="2"/> </bean> <!--3 sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <!--4 配置dao接口扫描包,动态的实现dao接口可以注入spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--注入 sqlSessionFactory--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--要扫描的dao包--> <property name="basePackage" value="com.hing.dao"/> </bean> </beans> -
spring整合service层
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--1 扫描service下的包--> <context:component-scan base-package="com.hing.service"/> <!--2 将我们所有的业务类注入到spring,可以通过配置或者注解实现--> <!--<bean id="BookServiceImpl" class="com.hing.service.BookServiceImpl">--> <!--<property name="bookMapper" ref="bookMapper"/>--> <!--</bean>--> <!--3 声明式事物配置--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据流--> <property name="dataSource" ref="dataSource"/> </bean> <!--4 aop事物支持!--> </beans>
SpringMvc层
-
applicationContext.xml,将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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="spring-dao.xml"/> <import resource="spring-service.xml"/> <import resource="spring-mvc.xml"/> </beans> -
web.xml
<!--DispatcherServlet-->
<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:applicationContext.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>
<!--乱码过滤-->
<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>
<!--session-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
- spring-mvc.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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">
<!--1 注解驱动-->
<mvc:annotation-driven/>
<!--2 静态资源过滤-->
<mvc:default-servlet-handler/>
<!--3 扫描包:controller-->
<context:component-scan base-package="com.hing.controller"/>
<!--4 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
启动测试
若出错则首先排查是否少jar包

Ajax技术
简介
Ajax=Asynchronous JavaScript and XML(异步的Javascript和XML)
Ajax是一种无需重新加载整个网页的情况下,能够更新部分网页的技术
Ajax不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术
Jquery Ajax
Jquery是js库,Jquery Ajax本质就是XMLHttpRequest,对他进行封装,方便调用。
jQuery 提供多个与 AJAX 有关的方法。
通过 jQuery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON - 同时您能够把这些外部数据直接载入网页的被选元素中。
提示:如果没有 jQuery,AJAX 编程还是有些难度的。
编写常规的 AJAX 代码并不容易,因为不同的浏览器对 AJAX 的实现并不相同。这意味着您必须编写额外的代码对浏览器进行测试。不过,jQuery 团队为我们解决了这个难题,我们只需要一行简单的代码,就可以实现 AJAX 功能。
jQuery load()方法
jQuery load() 方法是简单但强大的 AJAX 方法。
load() 方法从服务器加载数据,并把返回的数据放入被选元素中。
$(selector).load(URL,data,callback);
必需的 URL 参数规定您希望加载的 URL。
可选的 data 参数规定与请求一同发送的查询字符串键/值对集合。
可选的 callback 参数是 load() 方法完成后所执行的函数名称。
jQuery $.get() 方法
$.get(URL,callback);
必需的 URL 参数规定您希望请求的 URL。
可选的 callback 参数是请求成功后所执行的函数名。
$("button").click(function(){
$.get("demo_test.asp",function(data,status){
alert("Data: " + data + "\nStatus: " + status);
});
});
jQuery $.post() 方法
$.post(URL,data,callback);
必需的 URL 参数规定您希望请求的 URL。
可选的 data 参数规定连同请求发送的数据。
可选的 callback 参数是请求成功后所执行的函数名。
$("button").click(function(){
$.post("demo_test_post.asp",
{
name:"Donald Duck",
city:"Duckburg"
},
function(data,status){
alert("Data: " + data + "\nStatus: " + status);
});
});
jQuery noConflict() 方法
noConflict() 方法会释放会 $ 标识符的控制,这样其他脚本就可以使用它了。
$.noConflict();
jQuery(document).ready(function(){
jQuery("button").click(function(){
jQuery("p").text("jQuery 仍在运行!");
});
});
参考实例
验证用户名及密码的输入状态

-
创建Module标记Web支持
-
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"> <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:applicationContext.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> <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> </web-app> -
applicationContext.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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvn="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://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"> <mvn:annotation-driven/> <mvn:default-servlet-handler/> <context:component-scan base-package="com.hing.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="suffix" value=".jsp"/> <property name="prefix" value="/WEB-INF/jsp/"/> </bean> </beans> -
下载jquery文件,放到项目的web/statics/js/jquery-3.6.0.js

-
后台controller
package com.hing.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class AjaxController { @RequestMapping("/t1") public String t1(String username,String password){ String msg=""; if(username!=null){ if("admin".equals(username)){ msg="ok"; }else{ msg="name fail"; } } if(password!=null){ if("111111".equals(password)){ msg="ok"; }else{ msg="password fail"; } } return msg; } } -
页面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录页</title> <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.js" type="text/javascript"></script> <script> function t1() { $.post({ url:"${pageContext.request.contextPath}/t1", data:{"username":$("#username").val()}, success:function(data) { if (data.toString()=="ok"){ $("#usernameInfo").css("color","green"); }else{ $("#usernameInfo").css("color","red"); } $("#usernameInfo").html(data); } }) } function t2() { $.post({ url:"${pageContext.request.contextPath}/t1", data:{"password":$("#password").val()}, success:function(data) { if (data.toString()=="ok"){ $("#passwordInfo").css("color","green"); }else{ $("#passwordInfo").css("color","red"); } $("#passwordInfo").html(data); } }) } </script> </head> <body> <p> 用户名:<input type="text" id="username" onblur="t1()"> <span id="usernameInfo"></span> </p> <p> 密码:<input type="text" id="password" onblur="t2()"> <span id="passwordInfo"></span> </p> </body> </html> -
启动访问测试:登录页
拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter。用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
过滤器和拦截器的区别:拦截器是AOP思想的具体应用
- 过滤器
- servlet规范中的一部分,任何的JavaWeb工程都可以使用
- 在url-pattern中配置了/*以后,可以对所有要访问的资源进行拦截
- 拦截器
- 拦截器是SpringMvc自己的,只有使用了SpringMvc框架的工程才能使用
- 拦截器只会拦截访问的控制器的方法,如果访问的是jsp/html/css/images/js是不会进行拦截的
自定义拦截器
必须实现HandleInterceptor接口
-
新建Module,添加web支持
-
配置web.xml和springmvc-servlet.xml
-
编写拦截器 config/MyInterceptor
package com.hing.config; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("=======================处理前================================="); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("=======================处理后================================="); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("=======================清理================================="); } } -
springmvc-servlet.xml增加拦截器的配置
<!--拦截器配置--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.hing.config.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> -
controller
package com.hing.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @RequestMapping("/t1") public String test1(){ System.out.println("===============执行了test===================="); return "test"; } } -
启动测试访问:http://loaclhost:8080/t1
参考实例
用户登录判断验证
-
基于上个章节的自定义拦截器项目
-
创建导航页index.jsp、首页main.jsp、登录页login.jsp
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h1> <a href="${pageContext.request.contextPath}/user/goLogin">登录页</a> </h1> <h1> <a href="${pageContext.request.contextPath}/user/main">首页</a> </h1> </body> </html>main.jsp
<%-- Created by IntelliJ IDEA. User: Hengying.Zhang Date: 2021/11/18 Time: 13:35 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>首页</title> </head> <body> <h1>欢迎${username}</h1> <a href="${pageContext.request.contextPath}/user/goLogout">注销</a> </body> </html>login.jsp
<%-- Created by IntelliJ IDEA. User: Hengying.Zhang Date: 2021/11/18 Time: 13:32 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录页</title> </head> <body> <form action="${pageContext.request.contextPath}/user/login"> <h1> 用户名:<input type="text" name="username"> 密码:<input type="text" name="password"> <input type="submit" value="提交"> </h1> </form> </body> </html> -
定义LoginController
package com.hing.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpSession; @Controller @RequestMapping("/user") public class LoginController { //首页 @RequestMapping("/main") public String mian(){ return "main"; } //登录页面 @RequestMapping("/goLogin") public String goLogin(){ return "login"; } //登录 @RequestMapping("/login") public String login(String username, String password, HttpSession session, Model model){ session.setAttribute("userinfo",username); model.addAttribute("username",username); return "main"; } //注销 @RequestMapping("/goLogout") public String goLogout(HttpSession session){ session.removeAttribute("userinfo"); return "login"; } } -
定义拦截器LoginInterceptor
package com.hing.config; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //去往登录页则放行 if(request.getRequestURI().contains("goLogin")){ return true; } //首次登录放行 if(request.getRequestURI().contains("login")){ return true; } //如果是包含session信息则放行 if(request.getSession().getAttribute("userinfo")!=null){ return true; } //否则跳转到登录也 request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response); return false; } } -
拦截器配置springmvc-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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://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"> <mvc:annotation-driven/> <mvc:default-servlet-handler/> <context:component-scan base-package="com.hing.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <property name="suffix" value=".jsp"/> <property name="prefix" value="/WEB-INF/jsp/"/> </bean> <!--拦截器配置--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.hing.config.MyInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/user/**"/> <bean class="com.hing.config.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> </beans> -
启动测试,未登录下首页的访问
文件上传下载
文件上传是项目开发中最常见的功能之一,springMVC可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作,如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
前端表单要求:为了能上传文件,必须将表单的method设置成POST,并将enctype设置为multipart/form-data只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发生给服务器;
对表单的enctype属性做个详细的说明
- application/x-www=form-urlencoded:默认方式,只处理表单域中的value属性值,采用这种编码方式的表单会将表单域中的值处理成URL编码方式
- multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码
- text/plain:除了把空格转换为“+”号外,其他字符都不做编码的处理,这种方式适用直接通过表单发送邮件
<form action="" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" />
</form>
一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式处理表单的数据,而对应文件上传的处理则涉及在服务器端解析原始的HTTP响应。2003年,ApacheSoftwareFundation发布了开源的Commons FileUpload组件。其很快成为了Servlet/JSP程序员上传文件的最佳选择
- Servlet3.0规范已经提供方法来实现文件上传,但是这种上传需要在Servlet中完成
- 而SpringMVC则提供简单的封装
- SpringMVC为文件上传提供直接的支持,这种支持是用即插即用的MultipartResolve实现的
- SpringMVC使用的ApacheCommons FileUpload技术实现了一个MultipartResolve实现类:CommonsMultipartResolve。因此,SpringMVC的文件上传还需要依赖ApacheCommonsFileUpload的组件。
文件上传
-
导入文件上传的jar包,commons-fileupload。Maven会自动帮我们导入他的依赖包commons-io包
<!--文件上传--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> </dependency> <!--高版本的servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> -
配置bean:multipartResolve
注意!!!这个bean的id必须为:multipartResolve否则上传的文化会报404的错误!
<!--文件上传配置--> <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"> <!--请求的编码格式必须和JSP的pageEncoding属性一致,以便正确的读取表单的内容,默认的ISO8859-1--> <property name="defaultEncoding" value="utf-8"/> <!--上传文件大小的上限,单位为字节(10485760=10M)--> <property name="maxUploadSize" value="10485760"/> <property name="maxInMemorySize" value="40960"/> </bean>CommonsMultipartFile常用方法:
String getOriginalFilename() 获取上传文件的文件名 InputStream getInputStream() 获取文件流 void transferTo(File dest) 将上传文件保存到一个目录文件中 -
编写前端测试页面
<%-- Created by IntelliJ IDEA. User: Hengying.Zhang Date: 2021/11/18 Time: 14:35 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> <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post"> <input type="file" name="file"/> <input type="submit" value="upload"/> </form> </body> </html> -
controller
package com.hing.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.commons.CommonsMultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import javax.servlet.http.HttpServletRequest; import java.io.*; @RestController public class FileController { @RequestMapping("/upload") public String upload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException { //获取文件名 String uploadFilename = file.getOriginalFilename(); //如果文件名为空则直接回首页 if("".equals(uploadFilename)){ return "redirect:/index.jsp"; } System.out.println("上传文件名:"+uploadFilename); //上传路径保存设置 String path=request.getServletContext().getRealPath("/upload"); //路径不存在则创建路径 File realPath=new File(path); if (!realPath.exists()){ realPath.mkdir(); } System.out.println("上传文件保存地址:"+realPath); InputStream is=file.getInputStream();//文件输入流 OutputStream os= new FileOutputStream(new File(realPath,uploadFilename));//文件输出流 //读取写出 int len=0; byte[] buffer=new byte[1024]; while((len=is.read(buffer))!=-1){ os.write(buffer,0,len); os.flush(); } os.close(); is.close(); return "redirect:index.jsp"; } } -
测试上传文件!
file.transferTo来保存上传的文件
/**
* file.transferTo来保存上传的文件
*/
@RequestMapping("/upload2")
public String upload2(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
String path=request.getServletContext().getRealPath("/upload");
//路径不存在则创建路径
File realPath=new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));
return "redirect:index.jsp";
}
文件下载
- 设置response响应头
- 读取文件--inputStream
- 写出文件--OutputStream
- 执行操作
- 关闭流(先开后关)
public String downloads(HttpServletRequest request, HttpServletResponse response) throws IOException {
//要下载的图片地址
String path =request.getServletContext().getRealPath("/upload");
String fileName ="基础语法.jpg";
//1 设置response响应头
response.reset();//设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8");//字符编码
response.setContentType("multipart/form-data");//二进制传输数据
response.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
File file=new File(path,fileName);
//2 读取文件--输入流
InputStream input=new FileInputStream(file);
//3 写出文件--输出流
OutputStream out= response.getOutputStream();
byte[] buff=new byte[1024];
int index=0;
//4 执行写操作
while((index=input.read(buff))!=-1){
out.write(buff,0,index);
out.flush();
}
out.close();
input.close();
return null;
}

浙公网安备 33010602011771号