一、文件的下载
1.文件下载的实现步骤:
- 从服务器读取需要下载的文件;
(1)获取服务器的目录;
(2)设置属性下载文件的长度;
(3)设置下载文件的类型;
(4)设置响应头信息;- 把读取到的文件写入到本地。
2.代码的实现:
@RequestMapping("downLoad")
public void downLoad(String filename,String filetype,HttpServletRequest request,HttpServletResponse response) throws IOException{
//读取服务器中需要下载的文件
//获取服务器的目录
String realPath = request.getServletContext().getRealPath("/upload");
File file = new File(realPath+"/"+filename);
InputStream inputStream = new FileInputStream(file);
//设置属性下载到本地
//设置下载文件的长度
response.setContentLength((int) file.length());
//设置文件下载的类型
response.setContentType(filetype);
//设置响应头信息
response.setHeader("Content-Disposition","attachment;filename="+filename);
//把读取的文件写到本地
OutputStream outputStream = response.getOutputStream();
IOUtils.copy(inputStream, outputStream);
outputStream.close();
inputStream.close();
}
二、过滤器
1.使用过滤器解决请求的中文乱码(post请求)
- 自定义过滤器:
(1)创建Filter接口的实现类:
package com.zlw.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncFilter implements Filter {
//定义参数
String enc;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化参数
enc = filterConfig.getInitParameter("e");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//到达目标资源之前的预处理
request.setCharacterEncoding(enc);
//执行目标资源方法或者下一个过滤器
chain.doFilter(request, response);
//离开服务器之前的处理操作
}
@Override
public void destroy() {
}
}
(2)web.xml文件的配置:
<filter>
<filter-name>enc</filter-name>
<filter-class>com.bjsxt.filter.EncFilter</filter-class>
<init-param>
<param-name>e</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>enc</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
- 使用Spring中提供的字符编码过滤器:
<!-- 配置字符编码过滤器 -->
<filter>
<filter-name>encod</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>encod</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
三、拦截器
1.拦截器和过滤器的区别:
- 过滤器:
主要做三件事:
(1)达到目标资源之前的预处理;
(2)执行下一个过滤器或者目标资源;
(3)离开服务器之前的处理;
过滤器主要针对:我们配置的所有请求。
- 拦截器:
示例图主要针对的是控制单元的方法。
拦截器的底层就是AOP面向切面实现的;控制单元类似于切点;
使用拦截器需要在springmvc.xml配置文件中配置拦截器bean和拦截范围,配置全局拦截。
2.拦截器中的方法:
(1)preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2)
- 作用:拦截单元方法,返回值为false则拦截,返回值为true则放行 。
- 参数:
HttpServletRequest arg0,拦截的请求的request对象 ;
HttpServletResponse arg1, 拦截的请求的response对象 ;
Object arg2 封存了单元方法对象的HandleMethod对象 ;
(2)postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
- 作用:用于控制单元中模块的测试;恶意字符的替换。
- 参数:
HttpServletRequest arg0, 拦截的请求的request对象 ;
HttpServletResponse arg1, 拦截的请求的response对象 ;
Object arg2, 封存了单元方法对象的HandleMethod对象 ;
ModelAndView arg3 封存了单元方法的返回值资源路径和请求转到的Map数据 ;
(3) afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
- 作用:主要就是页面渲染操作和最后的垃圾回收。
- 参数:
HttpServletRequest arg0, 拦截的请求的request对象 ;
HttpServletResponse arg1, 拦截的请求的response对象 ;
Object arg2, 封存了单元方法对象的HandleMethod对象 ;
Exception arg3 存储了责任链的异常信息 ;
(4)拦截器方法执行的顺序:
preHandle--->单元方法--->postHandle--->afterCompletion
3.多拦截器:
SpringMVC多拦截器的执行顺序先进后出,是按照配置文件的先后;
- 例如:有两个拦截器MyInter2(先)和MyInter(后)
配置文件:
<!--全局配置-->
<mvc:interceptors>
<bean class="com.bjsxt.interceptor.MyInter2"></bean>
<bean class="com.bjsxt.interceptor.MyInter"></bean>
</mvc:interceptors>
执行顺序:
preHandle(Myinter2) --> preHandle(MyInter) --> 控制器方法(HandlerMethod) --> postHandle(MyInter) --> postHandle(MyInter2) --> afterCompletion(MyInter) --> afterCompletion(MyInter2);
4.代码示例:
- 配置文件:
<!-- 配置拦截器 -->
<mvc:interceptors>
<!--<bean class="com.bjsxt.interceptor.MyInter2"></bean> -->
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean id="my" class="com.zlw.interceptor.MyInceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
- 实现接口HandlerInterceptor:
package com.zlw.interceptor;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class MyInceptor implements HandlerInterceptor {
/**
* 执行的时机:在进入控制单元方法之前 这个方法的返回值决定了是否继续执行控制单元的方法 返回值是true就进入控制单元继续执行
* 返回值是false就不会继续执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
// 作用一:进行中文乱码的处理
request.setCharacterEncoding("utf-8");
// 作用二:进行页面的拦截
// response.sendRedirect("index.jsp");
System.out.println("preHandle!!!");
return true;
}
/**
* 执行时机:在进行数据处理之后 object:控制单元的方法 mv:视图模型对象
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,
ModelAndView modelAndView) throws Exception {
/**
* 作用一:用于控制单元中模块的测试 modelAndView.setViewName("redirect:/index.jsp")
*
* 作用二:恶意字符的替换 获取map集合中的值
*
*/
// modelAndView.setViewName("redirect:/index.jsp");
Map<String, Object> map = modelAndView.getModel();
String error = (String) map.get("error");
if (error.contains("XX")) {
String all = error.replaceAll("XX", "**");
map.put("error", all);
}
}
/**
* 执行时机:在进行页面渲染时执行 主要用于页面渲染操作和最后的垃圾回收
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception ex)
throws Exception {
System.out.println("afterComletion!!!");
}
}
四、SpringMVC的运行原理
1.SpringMVC运行原理:
(1)BeanDefinitionParser 接口,实现类负责解析配置文件中自定义命名空间对应的标签。
(2)<mvc:annotation-driven/> 实际注册了两个<bean> :
a.HandlerMapping接口的实现类DefaultAnnotationHandlerMapping, 判断URL合法性。
b.HandlerAdapter接口实现类AnnotationMethodHandlerAdapter,寻找@RequestMapping(),调用对应的方法。
2.核心组件(SpringMVC的四大组件):
(1)DispatchServlet: Servlet分发器,整个SPringMVC框架入口;
(2)HandlerMapping:寻找URL所请求的HandlerMethod,找@RequestMapping() ;
a.使用实现类DefaultAnnotationHandlerMapping实际工作;
(3)HandlerAdapter:实际调用HandlerMethod的组件;
a.使用实现类AnnotationMethodHandlerAdapter ;
(4)ViewResovler:视图解析器.作用解析HandlerMethod返回值,把逻辑视图转换为需要调用的物理视图。
a.自定义时:InternalResourceViewResolver;
3.使用的组件和接口:
(1)Controller : 控制器类 ;
(2)HandlerMethod: 控制器方法 ;
(3)View: 视图 ;
(4)Model: 模型;
(5)ModelAndView:模型和视图.SpringMVC所有HandlerMethod最终都会转换为ModelAndView;
(6)HandlerInterceptor: 拦截器 ;
(7)HandlerExceptionResolver:异常映射解析器;
(8)MultipartResolver: Multipart解析器 ;
(9)CharacterEncodingFilter: 字符编码过滤器 ;
4.SpringMVC运行原理图解:
-
详细图:
示例图 -
时序图:
时序图 -
SpringMVC请求处理流程:
处理流程
5.SpringMVC运行原理文字解释:
当用户发起请求后,执行DiapacherServlet,如果是JSP直接调用jsp页面。如果不是JSP,DiapacherServlet调用HandlerMapping判断请求URL是否合法,如果URL不存在报错,如果URL存在使用HandlerAdapter调用具体的HandlerMethod,当Handler执行完成后会返回ModelAndView,会被ViewResovler解析,调用具体的物理视图。最终响应给客户端浏览器。
五、邮箱系统的练习
1.需求:
(1)实现用户的登录;
(2)完成邮件信息的查询;
(3)完成邮件的发送;
2.实现步骤:
- 数据库创建表格:
- 用户表
create TABLE t_user(
uid int(5) PRIMARY key auto_increment,
uname VARCHAR(20),
pwd VARCHAR(20)
)
- 邮件表
create table t_email(
eid int(5) PRIMARY KEY auto_increment,
etitle VARCHAR(30),
econ VARCHAR(100),
filename VARCHAR(100),
recid int(10),
sendid int(10),
edate date
)
-
导包:
jar包 -
创建实体类(生成getter和setter及构造方法):
private int eid;
private String etitle;
private String econ;
private String filename;
private int recid;
private int sendid;
private Date edate;
private String uname;//用户名
private int uid;
private String uname;
private String pwd;
- 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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/bjsxt"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.zlw.pojo"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="factory"></property>
<property name="basePackage" value="com.zlw.mapper"></property>
</bean>
<context:component-scan base-package="com.zlw.service"></context:component-scan>
</beans>
- mapper接口和映射文件:
(1)EmailMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zlw.mapper.EmailMapper">
<select id="findMore" resultType="email">
select * from t_user u join t_email e
on u.uid = e.sendid
where e.recid = #{0}
</select>
<insert id="send" >
insert into t_email values(default,#{etitle},#{econ},#{filename},#{recid},#{sendid},#{edate})
</insert>
</mapper>
(2)UserMapper.xml
<mapper namespace="com.zlw.mapper.UserMapper">
<select id="findOne" resultType="user">
select *from t_user where uname = #{0} and pwd = #{1}
</select>
</mapper>
- test测试:
package com.zlw.test;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zlw.pojo.Email;
import com.zlw.service.UserService;
public class Test01 {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
UserService us = app.getBean("userService",UserService.class);
List<Email> list = us.findMore(1);
for (Email email : list) {
System.out.println(email.getUname());
}
}
}
结果
- web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>x_ssmEmail02</display-name>
<!-- 配置字符编码过滤器 -->
<filter>
<filter-name>encod</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>encod</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 核心配置 -->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- springmvc.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:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- @Contorller -->
<context:component-scan base-package="com.zlw.controller"></context:component-scan>
<!-- @RequestMapping -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置拦截器 -->
<!-- 创建上次文件的组件对象 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的名称中文乱码问题 -->
<property name="defaultEncoding" value="utf-8"></property>
</bean>
</beans>
- Controller控制单元:
(1)EmailController
package com.zlw.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import com.zlw.pojo.Email;
import com.zlw.pojo.User;
import com.zlw.service.UserService;
@Controller
public class EmailController {
@Autowired
private UserService userService;
//查询邮件
@RequestMapping("findEmail")
public String findEmail(HttpSession session,HttpServletRequest request){
User user = (User) session.getAttribute("user");
List <Email> list = userService.findMore(user.getUid());
request.setAttribute("list", list);
return "forward:/mian.jsp";
}
//发送邮件操作
@RequestMapping("send")
public String send(Email email,MultipartFile fl,HttpSession session) throws IllegalStateException, IOException{
User user = (User) session.getAttribute("user");
email.setFilename(fl.getOriginalFilename());
email.setEdate(new java.sql.Date(new Date().getTime()));
email.setSendid(user.getUid());
int i = userService.send(email);
fl.transferTo(new File("D:/img/"+fl.getOriginalFilename()));
if(i>0){
return "redirect:/success.jsp";
}
return "send.jsp";
}
}
(2)UserController
package com.zlw.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zlw.pojo.User;
import com.zlw.service.UserService;
@Controller
public class UserController {
@Autowired
private UserService userService;
//登录操作
@RequestMapping("login")
public String login(String uname,String pwd,HttpServletRequest request,HttpSession session){
User user = userService.findOne(uname, pwd);
if(user!=null){
session.setAttribute("user", user);
return "redirect:findEmail";
}
request.setAttribute("error", "登录失败!");
return "login.jsp";
}
}
- jsp页面:
(1)登录界面:
<body>
<form action="login" method="post">
<p>
用户名:<input type="text" name="uname" />${error }
</p>
<p>
密码:<input type="password" name="pwd" />
</p>
<p>
<input type="submit" value="登录" />
</p>
</form>
</body>
(2)邮件信息:
<body>
<table border="1px">
<tr>
<th>标题</th>
<th>时间</th>
<th>发送人</th>
</tr>
<c:forEach items="${list }" var="em">
<tr>
<th>${em.etitle }</th>
<th>${em.edate }</th>
<th>${em.uname}</th>
</tr>
</c:forEach>
</table>
<p>
<a href="send.jsp">发送邮件</a>
</p>
<p>
<a href="login.jsp">登录页面</a>
</p>
</body>
(3)发送邮件:
<body>
<form action="send" enctype="multipart/form-data" method="post">
<p>
收件人:<input type="text" name="recid"/>
</p>
<p>
主题:<input type="text" name="etitle"/>
</p>
<p>
正文:<input type="text" name="econ"/>
</p>
<p>
附件<input type="file" name="fl"/>
</p>
<p>
<input type="submit" value="发送"/>
</p>
</form>
</body>
(4)成功界面:
<body>
邮件发送成功!点击跳转<a href="findEmail">跳转</a>到主页面
</body>
3.实现效果:
-
登录界面:
登录 -
展现页面:
邮件信息 -
发送界面:
发送.png -
发送成功:
成功
网友评论