1,自定义DbUtils之MyBeanHandler
概念:封装单条记录的结果集处理
开发步骤:
- MyResultSetHandler接口上的泛型由MyBeanHandler的泛型确定
- 声明一个Class对象的引用
- 重写handle方法
代码实现:
public class MyBeanHandler<T> implements MyResultSetHandler<T> {
private Class<T> clazz;//可以是User,Student的Class对象,可以通过反射动态的设置属性值
public MyBeanHandler(Class clazz){
this.clazz = clazz;
}
@Override
public T handle(ResultSet resultSet) throws Exception {
T t = clazz.newInstance();
//处理结果集
while (resultSet.next()){
//id属性值,username属性值,password属性值
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//字段名
String fieldName = field.getName();
//字段值
Object fieldValue = resultSet.getObject(fieldName);
//将字段值设置Class对象对应的Java实体对象
//获取字段对应的set方法
String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Method method = clazz.getMethod(methodName,field.getType());
if(null!=method){
method.invoke(t,fieldValue);
}
}
}
return t;
}
}
2,自定义DbUtils之MyBeanListHandler
概念:封装多条记录的结果集处理
开发步骤:
- MyResultSetHandler接口上的泛型由MyBeanListHandler的泛型确定
–已经确定了返回的是集合,只是不确定集合中的元素类型
–MyBeanListHandler只确定集合中的元素类型就可以了 - 声明一个Class对象的引用
- 重写handle方法
代码实现:
public class MyBeanListHandler<T> implements MyResultSetHandler<List<T>> {
private Class<? extends T> clazz;//集合中的元素就是Class对象
public MyBeanListHandler(Class<? extends T> clazz){
this.clazz = clazz;
}
@Override
public List<T> handle(ResultSet resultSet) throws Exception {
List<T> list = new ArrayList<>();
while (resultSet.next()){
//循环一次,就是一条记录,就是一个对象
T t = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
Object fieldValue = resultSet.getObject(fieldName);
//获取set方法
String methodName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
Method method = clazz.getMethod(methodName,field.getType());
if (null !=method){
method.invoke(t,fieldValue);
}
}
list.add(t);
}
return list;
}
}
3,过滤器
概念:过滤器就是在一个用于请求之前处理资源的组件
生命周期:
- 随着服务器启动而初始化
- 随着请求的发出而过滤
- 随着服务器关闭而销毁
执行流程:
- 浏览器发起请求
- 服务器会根据这个请求,创建resquest对象及response对象
- 过滤器会持有request对象及response对象
- 只有当过滤器放行之后,request对象以及response对象才会传给Servlet
过滤器链:
- 根据配置顺序,遵从先过滤后放行原则
4,过滤器基本使用
开发步骤:
- 自定义类实现Filter接口
- 重写三个方法(init,doFilter,destroy)
- 在web.xml中配置过滤器(声明过滤器,配置过滤路径)
代码实现
过滤器
public class Demo01Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//过滤器的初始化
System.out.println("过滤器初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//过滤器处理请求
System.out.println("过滤器处理请求");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
//过滤器销毁
System.out.println("过滤器销毁");
}
}
web.xml
<!--声明Demo01过滤器-->
<filter>
<filter-name>Demo01Filter</filter-name>
<filter-class>filter.Demo01Filter</filter-class>
</filter>
<!--配置Demo01Filter的过滤路径-->
<filter-mapping>
<filter-name>Demo01Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5,过滤器相关配置
初始化参数配置
<filter>
<filter-name>Demo03Filter</filter-name>
<filter-class>filter.Demo03Filter</filter-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>root123</param-value>
</init-param>
</filter>
Filter获取初始化参数
public void init(FilterConfig config) throws ServletException {
Enumeration<String> parameterNames = config.getInitParameterNames();
while (parameterNames.hasMoreElements()){
String parameterName = parameterNames.nextElement();
String parameterValue = config.getInitParameter(parameterName);
System.out.println(parameterName+":"+parameterValue);
}
}
Filter过滤路径
- 针对,意为Filter仅针对Demo01Servlet进行过滤
<filter-mapping>
<filter-name>Demo03Filter</filter-name>
<servlet-name>Demo01Servlet</servlet-name>
</filter-mapping>
- 针对
完全匹配:必须以“/“开头
<filter-mapping>
<filter-name>Demo03Filter</filter-name>
<url-pattern>/aa</url-pattern>
</filter-mapping>
过滤器只过滤访问路径完全匹配“/aa”的资源
- 目录匹配:必须以“/”开头,以“*”结尾
<filter-mapping>
<filter-name>Demo03Filter</filter-name>
<url-pattern>/aa/bb/*</url-pattern>
</filter-mapping>
过滤器只过滤访问路径目录匹配到“/aa/bb/”
- 后缀名匹配:必须以“*”开头,以后缀名结尾
<filter-mapping>
<filter-name>Demo03Filter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
只过滤后缀名为jsp的文件
6,过滤器的注解开发
@WebFilter注解
-
WebInitParam[] initParams() default {};
配置初始化参数 -
String filterName() default “”;
配置过滤器名称 -
String[] servletNames() default {};
配置过滤的Servlet -
String[] urlPatterns() default {};
配置过滤路径
基本使用:
@WebFilter(filterName = "Demo04Filter",
urlPatterns = "/demo01",
servletNames = "Demo01Servlet",
initParams = {
@WebInitParam(name = "username",value="root"),
@WebInitParam(name = "password",value="root123")
})
public class Demo04Filter implements Filter {
public void init(FilterConfig config) throws ServletException {
Enumeration<String> parameterNames = config.getInitParameterNames();
while (parameterNames.hasMoreElements()){
String parameterName = parameterNames.nextElement();
String parameterValue = config.getInitParameter(parameterName);
System.out.println(parameterName+","+parameterValue);
}
......
}
执行顺序:按照过滤器的类名的字典顺序决定谁先过滤,谁先放行(比如:AFilter,BFilter,那么A就会先过滤,B先放行)
因此这里推荐使用web.xml来配置
7,过滤器案例之中文乱码
开发步骤:
- 自定义过滤器
- 完成请求参数中文乱码解决
代码实现
public class EncodingFilter implements Filter {
private String encoding = null;
public void init(FilterConfig config) throws ServletException {
encoding = config.getInitParameter("encoding");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//处理响应中文乱码
resp.setContentType("text/html;charset="+encoding);
//处理请求中文乱码
req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
}
public void destroy() {
}
}
web.xml
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7,过滤器应用之自动登录
开发步骤:
登录功能:
- 登录成功,将账户和密码存储到cookie中,跳转到首页
- 登录失败,转发到登录页面
自动登录:
- 判断访问资源是否和登录相关
- 如果是登录相关资源,直接放行
- 如果不是登录相关资源,进行自动登录
- 判断登录状态
- 如果已经是在登录状态,直接放行
- 如果不在登录状态,进行自动登录
- 获取cookie
- cookie为null(清理了浏览器缓存),转发到登录页面
- cookie不为null,进行自动登录
- 自动登录成功,修改登录状态,直接放行
- 自动登录失败(修改账户密码),转发到登录页面
- 获取cookie
- 判断登录状态
代码实现:
登录功能:
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if("root".equals(username)&&"root".equals(password)){
String autoLogin = request.getParameter("autoLogin");
if("autoLogin".equals(autoLogin)){
//进行自动登录,无非解释将用户信息保存起来,最合适的时cookie保存
Cookie cookie = new Cookie("autoLogin",username+"-"+password);
cookie.setMaxAge(7*24*60*60);
response.addCookie(cookie);
}
//登录成功,转发到一个页面,用来显示用户信息
User existUser = new User();
existUser.setUsername(username);
existUser.setPassword(password);
request.getSession().setAttribute("existUser",existUser);
request.getRequestDispatcher("/showIndex").forward(request,response);
}else {
//登录失败,转到登陆页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
自动登录功能:
@WebFilter(filterName = "AutoLoginFilter")
public class AutoLoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
//获取请求路径
String requestURI = request.getRequestURI();
//1,判断访问的资源是否和登录相关
if (requestURI.contains("login")){
//和登录相关资源,直接放行
chain.doFilter(request,resp);
}else {
//不是登录相关资源
//2,判断是否在登录状态
User existUser = (User) request.getSession().getAttribute("existUser");
if (null == existUser){
//不在登陆状态,自动登录
//获取Cookie
Cookie cookie = CookieUtils.getCookie(request.getCookies(), "autoLogin");
//判断cookie是否为空,存在浏览器缓冲清空
if(null==cookie){
//浏览器清理缓冲,相当于自动登录失败,跳转到登录页面,进行手动登录
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}else {
//还有缓存,进行自动登录
//获取用户信息
String infostr = cookie.getValue();
String[] infos = infostr.split("-");
String username = infos[0];
String password = infos[1];
if("root".equals(username)&&"root".equals(password)){
//自动登录成功,修改登录状态,直接放行,意味着还不在登陆状态
existUser = new User();
existUser.setUsername(username);
existUser.setPassword(password);
request.getSession().setAttribute("existUser",existUser);
chain.doFilter(req,resp);
}else {
//自动登录失败(别人修改了密码)
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}
}else {
//在登陆状态,直接放行
chain.doFilter(request,resp);
}
}
}
public void init(FilterConfig config) throws ServletException {
}
}