- SpringWeb
- 1.SpringWeb特点
- 2.SpringWeb运行流程
- 3.SpringWeb组件
- 4.搭建
- 项目结构图:
- 4.1导入jar包
- 4.2在Web.xml配置
- **4.2.1配置统一拦截分发器 DispatcherServlet**
- 4.2.2开启SpringWeb注解(spring.xml)
- 5.处理类的搭建
- 6.SpringWeb请求流程(自己理解)
- 7.接受请求
- @RequestMapping
- 8.补充ApiPost7使用(不需要前端直接测试后端)
- 9.获取请求数据
- 1.使用request对象接收
- 2.spring自动封装
- 3.@RequestParam("")进行参数绑 定.
- 4.使用实体类对象接受
- 5.日期类转换
- 10.中文乱码处理
- 11.跨域访问处理
- 12.返回json
- 13.拦截器
SpringWeb
SpringWeb是spring框架的一部分,是对web层进行封装
在 web 层框架历经 Strust1,WebWork,Strust2 等诸多产品的历代更选之后, 目前业界普遍选择了 springWeb 作为 Java EE 项目 web 层开发的首选方案
1.SpringWeb特点
pringWEB 是 spring 家族原生产品,与 IOC 容器等基础设施无缝对接.
- 基于原生的 Servlet,提供了一个前端控制器 DispatcherServlet ,开发者
无须额外开发控制器对象. - 可以自动绑定用户输入,并正确地转换数据类型.
- 代码清新简洁,大幅度提升开发效率.
- 内部组件化程度高,可插拔式组件即插即用.
- 性能卓著,尤其适合现代大型、超大型互联网项目要求.
2.SpringWeb运行流程
-
用户发送出请求到前端控制器
DispatcherServlet
。 -
DispatcherServlet
收到请求调用HandlerMapping
(处理器映射器)。 -
HandlerMapping
找到具体的处理器(可查找 xml 配置或注解配置),生成处 理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet
。 -
DispatcherServlet
调用HandlerAdapter
(处理器适配器)。 -
HandlerAdapter
经过适配调用具体的处理器(Handler/Controller)。 -
Controller
执行完成向前端响应结果
原理图:
3.SpringWeb组件
前端控制器:
DispatcherServlet
,由框架提供,在web.xml配置**作用:**统一处理请求和响应。整个流程控制的中心,由它组件处理用户的请求
**处理映射器:
HandlerMapping
**由框架提供作用:根据请求的url查找Handler
**处理器适配器
HandlerAdapter
**由框架提供。作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler
处理器
Handler
也称为Control需要自己开发注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可 以去正确执行Handler。
作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。
4.搭建
创建ssm web!!!项目根据前面搭建IOC AOP 事务管理的项目
项目结构图:
4.1导入jar包
<!-- springWeb -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.2.RELEASE</version>
</dependency>
完整的pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>ssm</artifactId><version>1.0-SNAPSHOT</version><name>ssm</name><packaging>war</packaging><properties><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.source>1.8</maven.compiler.source><junit.version>5.6.2</junit.version></properties><dependencies><!--spring-context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><!--spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.2.RELEASE</version></dependency><!--mybtais--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><!-- 阿里巴巴数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--spring集成mybatis需要的依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency><!--springweb层--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.2.RELEASE</version></dependency><!--servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!--jackson--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version></dependency><!--spring中提供的解决跨域问题的过过滤器--><dependency><groupId>com.thetransactioncompany</groupId><artifactId>cors-filter</artifactId><version>2.5</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.0</version></plugin></plugins></build>
</project>
4.2在Web.xml配置
必须是web项目
配置Web.xml文件
4.2.1配置统一拦截分发器 DispatcherServlet
<servlet><servlet-name>application</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml</param-value></init-param><load-on-startup>0</load-on-startup></servlet><!-- 请求映射 --><servlet-mapping><servlet-name>application</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
4.2.2开启SpringWeb注解(spring.xml)
<!-- 配置springmvc注解扫描--><mvc:annotation-driven/>
完整spring.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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--开启注解扫描 对指定包下面的类进行扫描, 检查添加有spring注解标签的类--><context:component-scan base-package="com.ffyc.ssm"> </context:component-scan><!--导入属性文件--><context:property-placeholder location="classpath:config.properties"/><!--让spring管理阿里巴巴数据库连接对象--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${url}"></property><property name="username" value="${uname}"></property><property name="password" value="${pwd}"></property><property name="initialSize" value="${initialSize}"></property><property name="maxActive" value="${maxActive}"></property></bean><!--spring管理生成SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><!--注入数据库连接对象--><property name="configLocation" value="classpath:mybatis.xml"></property><!--指定配置文件--><property name="mapperLocations" value="classpath:mappers/*Mapper.xml"><!--指定映射文件地址--></property></bean><!--spring管理生成接口的代理对象--><bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.ffyc.ssm.dao"></property><!--对指定包下的接口进行扫描,并生成接口的代理对象--><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean><!-- 配置 spring 事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 开启注解事务管理 --><tx:annotation-driven transaction-manager="transactionManager"/><!--开启web层的注解--><mvc:annotation-driven></mvc:annotation-driven><!--配置拦截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><!--定义哪些地址可以进入到拦截器中--><mvc:exclude-mapping path="/loginCtl/login"/><!--定义哪些地址不进入拦截器--><bean id="admintoken" class="com.ffyc.ssm.interceptor.AdminTokenInterceptor"></bean><!--配置拦截器的实现类--></mvc:interceptor></mvc:interceptors></beans>
注意:一定要检查spring.xml的配置
<!--导入属性文件--><context:property-placeholder location="classpath:config.properties"/>
5.处理类的搭建
package com.ffyc.ssm.web;import com.ffyc.ssm.model.Admin;
import com.ffyc.ssm.model.Result;
import com.ffyc.ssm.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.management.Agent;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
//@RequestMapping 用来为类和方法定义访问地址, 类上面的地址不能重复
@RequestMapping(path = "/loginCtl")
public class LoginController {@AutowiredLoginService loginService;@RequestMapping("/login")public String login() {System.out.println("hello Spring Web");return "login success";}}
@RestController
用于标记在一个类上,使用它标记的类就是一个 SpringWEB
控制器类.
Spring 配置中指定了自动扫描的 basepackage 后,Spring 会扫描这些包以及子包中的使用了@RestController 标识的类,然后将类加入到 Spring IOC 容器中,注入依赖。 @RequestMapping 注解是一个用来处理请求地址映射的注解,可用于类或方法上
@RequestMapping("/location")
注解是一个用来处理请求地址映射的注解,可用于类或方 法上。注:类上面的地址不允许重名,同一类内部方法的地址不允许重名
把项目部署在tomcat上运行,部署步骤
1.
2.
3.
注意:转换web项目时
要添加Artifacs:如图
4.
5.启动服务器
启动成功!!!
6.SpringWeb请求流程(自己理解)
- 用户发送出请求到前端控制器DispatcherServlet。
- DispatcherServlet 收到请求调用HandlerMapping(处理器映射器)。
- HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处
理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。 - DispatcherServlet 调用 HandlerAdapter(处理器适配器)。
- HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
- Controller 执行完成向前端响应结果
7.接受请求
@RequestMapping
/*@RequestMapping 是一个用来为处理器地址映射的注解,可用于类或方法上.
作用在类上,在整个项目中不能重复,作用在方法上,整个类中不能重复.
常用属性 path,value,method.
path 和value 用来定义地址
method 用来定义请求方式*/
@RequestMapping(value = "/hello",method = RequestMethod.GET)
@RequestMapping(path= "/hello",method = RequestMethod.POST)
案例:比如只允许post
@RequestMapping(path = "/login",method = RequestMethod.POST)public String login() {System.out.println("hello Spring Web");return "login success";}
8.补充ApiPost7使用(不需要前端直接测试后端)
1.安装ApiPost7
2.开始配置,点击API
2.配置接口
3.开始post、get测试
4.点击发送得到响应
5.后端响应
当然后端也可以更简单的接受前端post
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(String name, String age) {System.out.println("hello Spring Web");System.out.println(name +"and"+age);return "login success";}
也可以将前端数据封装在类中,当然前端传来的名称要与后端内容一致
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(Admin admin) {System.out.println("hello Spring Web");System.out.println(admin.getAccount());System.out.println(admin.getPassword());return "login success";}
那我们对获取请求数据来做具体介绍
9.获取请求数据
SpringWeb支持多种类型的请求参数进行封装
1.使用request对象接收
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(HttpServletRequest request) {System.out.println(request.getParameter("name"));return "login success";}
在处理中如果需要使用到HttpServletRequest 对象只需要定义即可
2.spring自动封装
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(String account,String password) {System.out.println("account: "+account+" password: "+password);return "login success";}
Spring 会自定进行数据封装,这里要注意的是,处理器接收参数的形参名称必须 和表单的name属性保持一致,否则会接收失败!
3.@RequestParam(“”)进行参数绑 定.
当请求参数名与形参名不一致时,可以使用
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(@RequestParam("account") String Useraccount,@RequestParam("password") String Userpassword) {System.out.println("account: "+Useraccount+" password: "+Userpassword);return "login success";}
表单的name和控制器的形参并不一致,但是@RequestParam注解的value 值必须和表单的name保持一致。
- @RequestHeader(“”)用来接收请求中的数据.
- @RequestHeader(“user-agent”)可以用来接收请求头中的数据
4.使用实体类对象接受
@RequestBody可以接收前端提交的json格式数据,将json格式封装到对象 中.
@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public String login(Admin admin) {Admin admin1 = loginService.login(admin);System.out.println(admin1);return "login success";}
5.日期类转换
属性类型为Date类型需要指定转换格式
@DateTimeFormat(pattern="yyyy-MM-dd")
privateDatebirthday
@DateTimeFormat(pattern = "yyyy-MM-dd")//给前端提交到后端的数据日期指定转换格式@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")//后端把对象转为json时,指定日期的格式private Date birthday;
如果前端是json格式的数据则需要在对象前添加如下标签@RequestBody
@RequestMapping(path = "/login",method = RequestMethod.POST)
public String login(@RequestBody Admin admin) {Admin admin1 = loginService.login(admin);System.out.println(admin1);return "login success";
}
tips:记得在pom.xml添加json组件
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version>
</dependency>
10.中文乱码处理
添加jar组件配置web.xml
<!--编码过滤器--><filter><filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
11.跨域访问处理
添加依赖pom.xml
<!--spring中提供的解决跨域问题的过过滤器--><dependency><groupId>com.thetransactioncompany</groupId><artifactId>cors-filter</artifactId><version>2.5</version></dependency>
web.xml配置
<!--跨域过滤器--><filter><filter-name>CORS</filter-name><filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class></filter><filter-mapping><filter-name>CORS</filter-name><url-pattern>/*</url-pattern></filter-mapping>
12.返回json
第一步添加依赖
<!--jackson-->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version>
</dependency>
Springweb 中 向 前 端 返 回数据为 json 时,只需要在方法上添加 @ResponseBody注解即可,
由于在类上面已经使用@RestController 注解,所以不需要再次添 加,@RestController 中已经包含
package com.ffyc.ssm.web;import com.ffyc.ssm.model.Admin;
import com.ffyc.ssm.model.Result;
import com.ffyc.ssm.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.management.Agent;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
//@RequestMapping 用来为类和方法定义访问地址, 类上面的地址不能重复
@RequestMapping(path = "/loginCtl")
public class LoginController {@AutowiredLoginService loginService;@RequestMapping(path = "/login",method = RequestMethod.POST)//直接接受前端的name与age(前提必须name对应前端的name)public Admin login(@RequestBody Admin admin) {Admin admin1 = loginService.login(admin);System.out.println(admin1);return admin;}}
运行tomcat 使用ApiPost测试
为了返回前端的代码,那我们写一个上面result.class
package com.ffyc.ssm.model;public class Result {private int code;private String message;private Object data;public Result() {}public Result(int code, String message, Object data) {this.code = code;this.message = message;this.data = data;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}
}
13.拦截器
Spring WEB中的拦截器(Interceptor)
类似于Servlet中的过滤器(Filter), 它主要用于拦截用户请求并作相应的处理。 Spring 中的拦截器与过滤器有着本质的区别,过滤器是servlet规范中定义并实 现的,在进入到servlet之前截获请求.而拦截器是spring中定义的一种拦截机制, 是对进入到处理器的请求进行拦截.
SpringWEB 定义了拦截器接口HandlerInterceptor
调用这个三个方法的时候,其参数的值也是从框架内部传递进来的。
boolean preHandle
预处理方法,实现处理器方法的预处理,就是在处理器方法执行之前这个方法会 被执行,相当于拦截了处理器方法,框架会传递请求和响应对象给该方法,第三 个参数为被拦截的处理器。如果preHandle方法返回true表示继续流程(如调 用下一个拦截器或处理器方法),返回false表示流程中断,不会继续调用其他 的拦截器或处理器方法,此时我们需要通过response来产生响应;
1.添加**AdminTokenInterceptor
**类拦截器
package com.ffyc.ssm.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;//定义拦截器
public class AdminTokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("进入到了拦截器");//获得tokenString token = request.getHeader("token");if(token.equals("123456")){return true; //拦截器中返回true, 请求就会离开拦截器,继续向后执行,到达处理器}else{response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("token验证失败");return false;//拦截器中返回false. 不会继续向后执行. 可以在拦截器中向用户做出响应}}
}
2.注册拦截器(spring.xml)
<!--配置拦截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><!--定义哪些地址可以进入到拦截器中--><mvc:exclude-mapping path="/loginCtl/login"/><!--定义哪些地址不进入拦截器--><bean id="admintoken" class="com.ffyc.ssm.interceptor.AdminTokenInterceptor"></bean><!--配置拦截器的实现类--></mvc:interceptor></mvc:interceptors>