这是一个学习的汇总,将学过的小知识点都展现出来。
高级过滤器作用:实现请求对象和相应对象的字符格式处理,兼容Tomcat7.0以下的服务器
数据传输请求:
1、GET:在tomcat7.0时没有对get请求进行优化而8.0进行了优化,在tomcat中的格式为iso-8859-1,数据在地址栏显示
2、POST:数据传输是打包的方式,地址栏不显示
高级过滤器的创建
1、创建过滤器,实现配置xml动态修改字符编码
package filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
public class EncodeFilter implements Filter{
private String encode;
public void init(FilterConfig fConfig) throws ServletException {
//获取web.xml中的字符配置数据
this.encode=fConfig.getInitParameter("encode");
System.out.println("过滤器启动...");
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain fChain)
throws IOException, ServletException {
//转换成HttpServletRequest类型
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response;
//设置请求对象的编码格式
req.setCharacterEncoding(encode);
//设置响应请求对象的字符编码格式
response.setContentType("text/html;charSet="+encode);
//装饰req对象,使之可以处理get方式的编码格式
fChain.doFilter(new MyRequest(req), resp);
}
/**
* 装饰者设计模式:
* 包装req和resp,使其在tomcat7以下处理get请求方式也能进行编码格式的处理
*/
private class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override
public String getParameter(String name) {
//获取当前参数
String value=request.getParameter(name);
//获取当前的请求方式
String methodName=request.getMethod();
if("GET".equals(methodName)){
try {
value=new String(value.getBytes("iso-8859-1"),encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return value;
}
}
}
2、将自己创建的类配置为web.xml的启动过滤器
<!-- 设置启动编码过滤器 -->
<filter>
<!-- 名字随意 -->
<filter-name>filterEncoding</filter-name>
<!-- 自己创建的过滤器类路径 -->
<filter-class>filter.EncodeFilter</filter-class>
<!-- 初始化项,自定义字符编码格式 -->
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- 和上面的名字要一样 -->
<filter-name>filterEncoding</filter-name>
<!-- 过滤所有请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
BaseServlet的创建
仿Spring的controller,baseServlet只处理返回值为字符串的和没有返回值的方法,再通过反射调用子类的方法,其子类方法定义为public String xxXXX(req,resp)或者public void xxXXX(req,resp)
1、创建BaseServlet
package baseservlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import utils.logs.InitLog4j;
public class BaseServlet extends HttpServlet {
protected Logger log = Logger.getLogger(InitLog4j.class);
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取方法名称
String methodName=request.getParameter("method");
//获取当前servlet的类
Class<? extends BaseServlet> clazz = this.getClass();
try {
//获取要执行的方法
Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
//获取当前方法的返回值
String returnType = method.getReturnType().getSimpleName();
//判断
if(!"void".equals(returnType)&&"String".equals(returnType)){
//执行方法获取返回值
String path = (String) method.invoke(this, request,response);
request.getRequestDispatcher(path).forward(request, response);
}else {
method.invoke(this, request,response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
poi将excel数据导入持久化到数据库(子类controller,继承BaseServet)
package controller;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import baseservlet.BaseServlet;
import utils.DBUtil;
@WebServlet("/importExcel")
public class ImportExcelDateController extends BaseServlet {
private static final long serialVersionUID = 1L;
public void importExcel(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件对象输入流对象需要commons-io.jar,commons-uploadfille.jar
//1创建文件解析器对象
DiskFileItemFactory fileItemFactory=new DiskFileItemFactory();
//2设置缓存对象大小
fileItemFactory.setSizeThreshold(1024*1024*10);
//3设置文件上传存储的临时目录
fileItemFactory.setRepository(new File("C:\temp"));
//4创建一个文件解析对象
ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
try {
//5使用解析器将http对象转换成文件项目集合对象
List<FileItem> list = servletFileUpload.parseRequest(req);
//判断文件集合是否为空
if(list!=null&&list.size()>0){
//获取form表单中的第一项file
FileItem fileItem = list.get(0);
//获取上传文件的路径(兼容性)IE:"C:a/b/x.xls" 非IE:x.xls
String path=fileItem.getName();
//将双引号去掉并小写
String name=path.replaceAll("\"", "").toLowerCase();
//获取对应文件的输入流
InputStream inputStream = fileItem.getInputStream();
// 获取excel中的数据,并导入数据库
importDateExcel(name,inputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取excel中的数据
*/
private void importDateExcel(String name, InputStream inputStream) {
//定义工作簿的引用
Workbook workbook=null;
try {
//兼容性
if(name.endsWith(".xls")){//2003 poi.jar
workbook=new HSSFWorkbook(inputStream);
}else if(name.endsWith(".xlsx")){//2007 poi-ooxml.jar
workbook=new XSSFWorkbook(inputStream);
}
//将excel数据进行解析
//1拿到工作表
Sheet sheet = workbook.getSheetAt(0);
//获取sheet对象中的每一行
Iterator<Row> iterator = sheet.iterator();
//跳过表头
iterator.next();
//sql语句
String sql="INSERT INTO `testdb`.`t_user` (`user_name`, `user_sex`) VALUES (?,?)";
//遍历迭代器
while (iterator.hasNext()) {
//获取这一行
Row row = iterator.next();
String userName = row.getCell(0).getStringCellValue();
String userSex=row.getCell(1).getStringCellValue();
//执行sql语句
DBUtil.doUpdate(sql, userName,userSex);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
配置log4j
1、准备log4j.properties文件
log4j.rootLogger=DEBUG, Console, infoFile, File
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
#infoFile
log4j.appender.infoFile=org.apache.log4j.RollingFileAppender
log4j.appender.infoFile.layout=org.apache.log4j.PatternLayout
log4j.appender.infoFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.appender.infoFile.MaxFileSize=10MB
log4j.appender.infoFile.MaxBackupIndex=10
log4j.appender.infoFile.File=/var/log/debug.log
#File
#配置log4j每天产生日志,并且当天日志大于10M时自动生成另一个文件
log4j.appender.File=org.apache.log4j.RollingFileAppender
#可以灵活地指定布局模式
log4j.appender.File.layout=org.apache.log4j.PatternLayout
#自定义输出日志格式
log4j.appender.File.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#当文件大小超过10MB时,默认将原来的文件名改为auto.log.1
log4j.appender.File.MaxFileSize=10MB
#保留10个备份文件
log4j.appender.File.MaxBackupIndex=10
#输出日志文件路径,winodows下回存放在和工作空间同级目录下的/var/log文件夹中,linux下会直接存放在/var/log文件夹下
log4j.appender.File.File=/var/log/info.log
#Threshold:入口,临界值。只有INFO级别以及以上级别的日志才会输出到日志中
log4j.appender.File.Threshold=INFO
#如果配置下面的,则每天会产生一个日志文件
#log4j.appender.File=org.apache.log4j.DailyRollingFileAppender
#今天是2016-12-15,到明天这个文件将更名为debug.log.2016-12-16。
#log4j.appender.File.DatePattern='.'yyyy-MM-dd
#每天:’.’YYYY-MM-dd(默认)
#每星期:’.’YYYY-ww
# 每月:’.’YYYY-MM
#每隔半天:’.’YYYY-MM-dd-a
#每小时:’.’YYYY-MM-dd-HH
#每分钟:’.’YYYY-MM-dd-HH-mm
2、创建初始化log文件的类
package utils.logs;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.log4j.PropertyConfigurator;
public class InitLog4j extends HttpServlet{
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
String file = getInitParameter("log4j-init-file");
//如果文件不存在则不初始化
if (file != null) {
//类加载器加载配置文件
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(file);
PropertyConfigurator.configure(inputStream);
}else {
System.out.println("log没有初始化....");
}
}
}
PropertyConfigurator.configure(inputStream)的初始化log配置文件,有很多人用的是路径,但是经常会空指针异常,因为路径这个新手很容易出错,所以建议使用url或者流或者配置类型来初始化,具体可以配置的参数类型为:
3、web.xml配置log跟随web容器初始化
<!-- 日志 -->
<servlet>
<servlet-name>log</servlet-name>
<!-- 自定义的log初始化类 -->
<servlet-class>utils.logs.InitLog4j</servlet-class>
<init-param>
<param-name>log4j-init-file</param-name>
<param-value>log4j.properties</param-value>
</init-param>
<!-- 大于等于零,就随web容器一起初始化 -->
<load-on-startup>1</load-on-startup>
</servlet>
4、log的使用方法,简单的列几个例子
//定义log对象
/*日志记录的优先级从高到低,分为 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 ALL 或者您定义的级别*/
protected Logger log = Logger.getLogger(InitLog4j.class);
//debug一般在开始和结束的时候使用
log.debug("log4j启动了");
log.info("sss");
//一般在if条件中使用
log.error("错误");
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="importExcel?method=importExcel" method="post" enctype="multipart/form-data">
<input type="file" name="upload"/>
<input type="submit" value="导入"/>
</form>
</body>
</html>
数据库CRUD的封装DBUtils
package utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;
/**
* 通用数据库工具类
* @author Administrator
*/
public class DBUtil {
private static String DRIVER;
private static String URL;
private static String USERNAME;
private static String PASSWORD;
private static Connection conn;
private static PreparedStatement ps;
private static Properties properties=new Properties();
/*
静态块,该区域代码只会在类初始化时执行一次,不会反复执行
*/
static{
try {
InputStream intputstream=DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
properties.load(intputstream);
DRIVER=properties.getProperty("DRIVER");
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
System.out.println("请检查驱动包或者驱动类路径");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取数据库连接
* @return
*/
public static Connection getConn(){
URL=properties.getProperty("URL");
USERNAME=properties.getProperty("USERNAME");
PASSWORD=properties.getProperty("PASSWORD");
try {
//ctrl+shift+x/y 大小写转换
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 关闭资源
*/
public static void close(Statement ps,Connection conn){
try {
if(ps != null){
ps.close();
}
if(conn != null)
{
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 封装通用的增 删 改操作
* @param sql
* @param params
* @return
*/
public static int doUpdate(String sql,Object... params){
try {
conn = getConn();
ps = conn.prepareStatement(sql);
for(int i = 0;i<params.length;i++)
{
ps.setObject(i+1, params[i]);
}
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally{
close(ps, conn);//关闭资源必须在finally中
}
return 0;
}
/**
* 封装通用查询
* @param sql
* @param params
*/
public static List<?> doQuery(String sql,CallBack call,Object... params){
try {
conn = getConn();
ps = conn.prepareStatement(sql);
for(int i = 0;i<params.length;i++)
{
ps.setObject(i+1, params[i]);
}
ResultSet rs = ps.executeQuery();
return call.getResults(rs);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public interface CallBack{
//回调函数(钩子函数)
List<?> getResults(ResultSet rs);
}
}
数据配置文件db.properties:
DRIVER=com.mysql.jdbc.Driver
URL=jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8&useSSL=true
USERNAME=root
PASSWORD=123
我的项目的分层