package cn.mldn.util.servlet;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jspsmart.upload.SmartUpload;
import cn.mldn.util.bean.BeanValueUtil;
import cn.mldn.util.split.SplitPageUtils;
import cn.mldn.util.vaildator.Validation;
@SuppressWarnings("serial")
public abstract class DispatcherServlet extends HttpServlet {
protected HttpServletRequest request; // 定义request对象
protected HttpServletResponse response; // 定义reponse对象
private ResourceBundle pageResource; // 读取Pages.properties对象
private ResourceBundle messageResource; // 读取Messages.properties是对象
private SmartUpload smart;
@Override
public void init() throws ServletException {
this.pageResource = ResourceBundle.getBundle("Pages", Locale.getDefault());
this.messageResource = ResourceBundle.getBundle("Messages", Locale.getDefault());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.request = request;
this.response = response;
String urlPage = "error.page";
String status = this.getStatus();
try {
if (status != null) { // 此时有一个状态码,好区分不同的用户请求
String contentType = request.getContentType();
if (contentType != null && contentType.contains("multipart/form-data")) {
try {
this.smart = new SmartUpload();
this.smart.initialize(super.getServletConfig(), this.request, this.response);
this.smart.upload();
} catch (Exception e) {
}
}
Map<String, String> errors = Validation.validate(this);
if (errors.size() == 0) { // 没有错误
this.parameterHandle(); // 处理所有的提交参数
try {
Method statusMethod = this.getClass().getMethod(status);
urlPage = statusMethod.invoke(this).toString();
} catch (Exception e) {
e.printStackTrace();
}
} else { // 回到指定的错误页上
request.setAttribute("errors", errors);
urlPage = this.getClass().getSimpleName() + "." + status + ".error.page";
}
}
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(this.getPageValue(urlPage)).forward(request, response);
}
/**
* 取得当前的业务调用的参数
*
* @return
*/
public String getStatus() {
String uri = request.getRequestURI(); // 取得URI,内容:/DispatcherProject/EmpServlet/edit
String status = uri.substring(uri.lastIndexOf("/") + 1);
return status;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
/**
* 取得指定参数对应的内容,不关心表单是否被封装
*
* @param paramName
* @return
*/
public String getStringParameter(String paramName) {
String contentType = request.getContentType();
if (contentType != null && contentType.contains("multipart/form-data")) {
return this.smart.getRequest().getParameter(paramName);
} else {
return this.request.getParameter(paramName);
}
}
/**
* 取得指定参数并且将其变为int型数据返回
*
* @param paramName
* @return
*/
public int getIntParameter(String paramName) {
return Integer.parseInt(this.getStringParameter(paramName));
}
/**
* 取得指定参数并且将其变为int型数据返回
*
* @param paramName
* @return
*/
public double getDoubleParameter(String paramName) {
return Double.parseDouble(this.getStringParameter(paramName));
}
/**
* 取得指定参数并且将其变为Date型数据返回
*
* @param paramName
* @return
*/
public Date getDateParameter(String paramName) {
try {
return new SimpleDateFormat("yyyy-MM-dd").parse(this.getStringParameter(paramName));
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 取得指定参数并且将其变为Date类型
*
* @param paramName
* @return
*/
public Date getDatetimeParameter(String paramName) {
try {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.getStringParameter(paramName));
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* 实现所有请求参数与VO类转换的处理操作
*/
private void parameterHandle() {
String contentType = request.getContentType();
if (contentType != null && contentType.contains("multipart/form-data")) { // 表单封装
// 1、处理SmartUpload对象实例化问题
try {
Enumeration<String> enu = this.smart.getRequest().getParameterNames();
while (enu.hasMoreElements()) { // 取得全部的参数名称
String paramName = enu.nextElement();
String paramValue = this.smart.getRequest().getParameter(paramName);
new BeanValueUtil(this, paramName, paramValue).setObjectValue();
}
} catch (Exception e) {
}
} else {
// 1、需要取得全部的请求参数名称
Enumeration<String> enu = this.request.getParameterNames();
while (enu.hasMoreElements()) { // 取得全部的参数名称
String paramName = enu.nextElement();
String paramValue = this.request.getParameter(paramName);
new BeanValueUtil(this, paramName, paramValue).setObjectValue();
}
}
}
/**
* 设置业务操作完成之后的跳转路径与提示信息的Key
*
* @param pageKey
* 对应的Pages.properties文件中指定的key信息
* @param messageKey
* 对应的Messages.properties文件中指定的key信息
*/
public void setUrlAndMsg(String pageKey, String messageKey) {
this.request.setAttribute("url", this.getPageValue(pageKey));
if (this.getType() == null || "".equals(this.getType())) {
this.request.setAttribute("msg", this.getMessageValue(messageKey));
} else { // 将之前设置的每一个Servlet中的占位符进行了替换
this.request.setAttribute("msg", MessageFormat.format(this.getMessageValue(messageKey), this.getType()));
}
}
/**
* 取得Pages.properties文件中指定的key对应的value内容
*
* @param pageKey
* 要读取的资源文件的key信息
* @return
*/
public String getPageValue(String pageKey) {
return this.pageResource.getString(pageKey);
}
/**
* 创建新的上传文件名称
* @return
*/
public String createSingleFileName() {
return UUID.randomUUID() + "." + this.smart.getFiles().getFile(0).getFileExt() ;
}
/**
* 进行文件的保存处理
*/
public boolean saveUploadFile(String fileName) {
try {
if (this.getUploadDir() == null || "".equals(this.getUploadDir())) {
this.smart.getFiles().getFile(0).saveAs(super.getServletContext().getRealPath("/") + fileName);
} else {
String filePath = super.getServletContext().getRealPath("/") + this.getUploadDir() + fileName ;
File file = new File(filePath) ;
if (!file.getParentFile().exists()) { // 保存目录不存在
file.getParentFile().mkdirs() ;
}
this.smart.getFiles().getFile(0).saveAs(filePath);
}
return true ;
} catch (Exception e) {
return false ;
}
}
/**
* 判断是否有上传文件
* @return
*/
public boolean isUploadFile() { // 是否存在有上传文件
if (this.smart == null) {
return false ;
}
try {
if (this.smart.getFiles().getSize() > 0) {
return true ;
}
} catch (IOException e) {
return false ;
}
return false ;
}
/**
* 取得Messages.properties文件中指定的key对应的value内容
*
* @param messageKey
* 要读取的资源文件的key信息
* @return
*/
public String getMessageValue(String messageKey) {
return this.messageResource.getString(messageKey);
}
/**
* 将分页所需要的参数都使用request属性传递
* @param urlKey 分页执行要使用到url
* @param allRecorders 总的记录数
* @param spu 分页的相关参数
*/
public void setSplitPage(String urlKey,int allRecorders,SplitPageUtils spu) {
this.request.setAttribute("url", this.getPageValue(urlKey));
this.request.setAttribute("allRecorders", allRecorders);
this.request.setAttribute("currentPage", spu.getCurrentPage());
this.request.setAttribute("lineSize", spu.getLineSize());
this.request.setAttribute("column", spu.getColumn());
this.request.setAttribute("keyWord", spu.getKeyWord());
this.request.setAttribute("columnData", this.getDefaultColumn());
}
/**
* 设置所有分页的候选列,格式安按照“标签:列名称|标签:列名称|”
* @return
*/
public abstract String getDefaultColumn() ;
/**
* 取得上传文件保存目录
* @return
*/
public abstract String getUploadDir() ;
/**
* 取得每一个子类的具体的操作类型,以作为消息的填充使用
*
* @return 返回每一个模块的名称
*/
public abstract String getType();
}
package cn.mldn.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import cn.mldn.util.servlet.DispatcherServlet;
import cn.mldn.util.split.SplitPageUtils;
import cn.mldn.vo.Emp;
@SuppressWarnings("serial")
@WebServlet(urlPatterns="/EmpServlet/*")
// 列表操作:http://localhost/DispatcherProject/EmpServlet/list
// 增加操作:http://localhost/DispatcherProject/EmpServlet/add
// 修改操作:http://localhost/DispatcherProject/EmpServlet/edit
public class EmpServlet extends DispatcherServlet {
private Emp emp = new Emp() ;
public Emp getEmp() {
return emp;
}
public String list()
throws ServletException, IOException {
String urlKey = "EmpServlet.list.servlet" ;
SplitPageUtils spu = new SplitPageUtils(super.request) ;
int currentPage = spu.getCurrentPage() ;
int lineSize = spu.getLineSize() ;
int empCount = 55 ; // 这个代表总记录数
List<Emp> all = new ArrayList<Emp>() ;
for (int x = (currentPage - 1) * lineSize; x < currentPage * lineSize; x++) {
Emp emp = new Emp() ;
emp.setEmpno(1000 + x);
emp.setEname("雇员姓名 - " + spu.getColumn() + " - " + spu.getKeyWord() + " - " + x);
all.add(emp) ;
}
request.setAttribute("allEmps", all); // 这个值需要传递给JSP页面
super.setSplitPage(urlKey, empCount, spu);
System.out.println("***** 【Servlet输出】列表雇员信息。" + super.request.getRemoteAddr());
return "emp.list.page" ;
}
public String remove()
throws ServletException, IOException {
System.out.println("***** 【Servlet输出】删除雇员信息。");
return "forward.page" ;
}
public String edit()
throws ServletException, IOException {
System.out.println("***** 【Servlet输出】编辑雇员信息。");
return "forward.page" ;
}
public String add()
throws ServletException, IOException {
System.out.println("***** 【Servlet输出】增加雇员信息。" + this.emp);
if (super.isUploadFile()) { // 现在有文件上传
String fileName = super.createSingleFileName() ;
// 而后这个文件名称一定手工设置到VO类对象之中
super.saveUploadFile(fileName) ; // 保存文件
}
super.setUrlAndMsg("emp.add.page", "vo.add.success.msg");
return "forward.page" ;
}
@Override
public String getType() {
return "雇员";
}
@Override
public String getUploadDir() {
return "/upload/emp/";
}
@Override
public String getDefaultColumn() {
return "雇员姓名:ename|雇员职位:job|联系电话:phone|邮箱:email";
}
}
本类的功能是根据当前的servlet对象以及参数的内容实现属性的设置。
package cn.mldn.util.bean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import cn.mldn.util.StringUtils;
/**
* 本类的功能是根据当前的servlet对象以及参数的内容实现属性的设置。
* 前提:操作VO对象一定在Servlet类中实例化完成,并且提供有相应的getter方法。
* @author mldn
*/
public class BeanValueUtil {
private Object servletObject ; // 传入的Servlet对象
private String attributeName ; // 属性的名字,带有“.”
private String attributeValue ; // 属性的内容,通过外部的request.getParameter()接收的
/**
* 传入所需要的对象
* @param servletObject 触发此操作的Servlet对象
* @param attributeName 传入的参数名称
* @param attributeValue 传入的参数内容
*/
public BeanValueUtil(Object servletObject, String attributeName, String attributeValue) {
this.servletObject = servletObject;
this.attributeName = attributeName.trim();
this.attributeValue = attributeValue.trim();
}
/**
* 实现属性内容的设置处理,将参数的内容设置给指定VO类的属性
*/
public void setObjectValue() { // 实现内容的设置
Object currentObject = null ; // 描述的是当前的VO类对象
if (this.attributeName.contains(".")) { // 如果包含有:“.”则认为此时的内容可以处理
String result [] = this.attributeName.split("\\.") ; // 按照“.”拆分
try {
Method getMethod = this.servletObject.getClass().getMethod("get" + StringUtils.initcap(result[0])) ;
currentObject = getMethod.invoke(this.servletObject) ;
if (result.length == 2) { // 单级控制
Field field = currentObject.getClass().getDeclaredField(result[1]) ; // 取得指定属性的对象
Method setMethod = currentObject.getClass().getMethod("set" + StringUtils.initcap(result[1]), field.getType()) ;
setMethod.invoke(currentObject, this.convertValue(field.getType().getSimpleName())) ; // 实现了setter调用
} else { // 多级控制
for (int x = 1 ; x < result.length - 1 ; x ++) {
Field subField = currentObject.getClass().getDeclaredField(result[x]) ;
Method getSubMethod = currentObject.getClass().getMethod("get" + StringUtils.initcap(result[x])) ;
if (getSubMethod.invoke(currentObject) == null) { // 表示类中的对象还未被初始化
currentObject = this.objectNewInstance(currentObject, result[x], subField) ;
} else {
currentObject = getSubMethod.invoke(currentObject) ;
}
}
Field attField = currentObject.getClass().getDeclaredField(result[result.length - 1]) ;
Method attMethod = currentObject.getClass().getMethod("set" + StringUtils.initcap(result[result.length - 1]), attField.getType()) ;
attMethod.invoke(currentObject, this.convertValue(attField.getType().getSimpleName())) ;
}
} catch (Exception e) {
// e.printStackTrace();
}
}
}
/**
* 反射调用setter方法实现对象的实例化控制
* @param currentObject 当前的对象
* @param attr 属性
* @param field 对象所属的类型,只有知道类型才可以反射实例化对象
* @return 一个实例化好的对象
*/
private Object objectNewInstance(Object currentObject, String attr, Field field) throws Exception {
Object newObject = field.getType().newInstance(); // 反射实例化对象
Method setMethod = currentObject.getClass().getMethod("set" + StringUtils.initcap(attr), field.getType());
setMethod.invoke(currentObject, newObject);
return newObject;
}
/**
* 因为传入的数据都是String,所以需要将其变为指定的类型
* @return
*/
private Object convertValue(String type) {
if ("int".equals(type) || "Integer".equals(type)) {
return Integer.parseInt(this.attributeValue) ; // 将内容变为整数
}
if ("double".equalsIgnoreCase(type)) {
return Double.parseDouble(this.attributeValue) ;
}
if ("date".equalsIgnoreCase(type)) {
try {
if (this.attributeValue.matches("\\d{4}-\\d{2}-\\d{2}")) {
return new SimpleDateFormat("yyyy-MM-dd").parse(this.attributeValue);
}
if (this.attributeValue.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.attributeValue);
}
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
return this.attributeValue ;
}
}
package cn.mldn.util.split;
import javax.servlet.http.HttpServletRequest;
public class SplitPageUtils {
private HttpServletRequest request ;
public SplitPageUtils(HttpServletRequest request) {
this.request = request ;
}
public Integer getCurrentPage() {
int currentPage = 1 ;
try {
currentPage = Integer.parseInt(this.request.getParameter("cp")) ;
} catch (Exception e) {}
return currentPage ;
}
public Integer getLineSize() {
int lineSize = 10 ;
try {
lineSize = Integer.parseInt(this.request.getParameter("ls")) ;
} catch (Exception e) {}
return lineSize ;
}
public String getColumn() {
String column = this.request.getParameter("col") ;
return column ;
}
public String getKeyWord() {
String keyWord = this.request.getParameter("kw") ;
return keyWord ;
}
}
进行数据的验证操作处理
package cn.mldn.util.vaildator;
import java.util.HashMap;
import java.util.Map;
import cn.mldn.util.ResourceUtils;
import cn.mldn.util.servlet.DispatcherServlet;
public class Validation {
private Validation() {}
/**
* 进行数据的验证操作处理,如果要是有错误出现(即,不满足验证规则,那么会将错误信息保存在Map集合里面)<br>
* Map集合会保存两个内容:<br>
* <li>key = 参数的名称;</li>
* <li>value = 错误的完整信息;</li>
* @param servlet 因为整个的处理之中需要进行Pages、Messages、getXxx()的参数操作
* @return
*/
public static Map<String,String> validate(DispatcherServlet servlet) {
Map<String,String> errors = new HashMap<String,String>() ;
String ruleKey = servlet.getClass().getSimpleName() + "." + servlet.getStatus() + ".rules" ;
try {
String rule = ResourceUtils.get("Validations", ruleKey) ;
if (rule != null) { // 可以应用规则
String result [] = rule.split("\\|") ;
for (int x = 0 ; x < result.length ; x ++) { // 开始取出每一个规则进行检测
String temp [] = result[x].split(":") ;
String val = servlet.getStringParameter(temp[0]) ;
switch(temp[1]) {
case "string" : {
if (!Validation.validateEmpty(val)) { // 验证失败
errors.put(temp[0], servlet.getMessageValue("validation.string.msg")) ;
}
break ;
}
case "int" : {
if (!Validation.validateInt(val)) { // 验证失败
errors.put(temp[0], servlet.getMessageValue("validation.int.msg")) ;
}
break ;
}
case "double" : {
if (!Validation.validateDouble(val)) { // 验证失败
errors.put(temp[0], servlet.getMessageValue("validation.double.msg")) ;
}
break ;
}
case "date" : {
if (!Validation.validateDate(val)) { // 验证失败
errors.put(temp[0], servlet.getMessageValue("validation.date.msg")) ;
}
break ;
}
case "datetime" : {
if (!Validation.validateDatetime(val)) { // 验证失败
errors.put(temp[0], servlet.getMessageValue("validation.datetime.msg")) ;
}
break ;
}
}
}
}
} catch (Exception e) { // 出现了错误,就表示没有规则
e.printStackTrace();
}
return errors ;
}
/**
* 验证数据是否是日期
* @param val
* @return
*/
public static boolean validateDatetime(String val) {
if (validateEmpty(val)) {
return val.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}") ;
}
return false ;
}
/**
* 验证数据是否是日期
* @param val
* @return
*/
public static boolean validateDate(String val) {
if (validateEmpty(val)) {
return val.matches("\\d{4}-\\d{2}-\\d{2}") ;
}
return false ;
}
/**
* 验证数据是否是小数
* @param val
* @return
*/
public static boolean validateDouble(String val) {
if (validateEmpty(val)) {
return val.matches("\\d+(\\.\\d+)?") ;
}
return false ;
}
/**
* 验证数据是否是整数
* @param val
* @return
*/
public static boolean validateInt(String val) {
if (validateEmpty(val)) {
return val.matches("\\d+") ;
}
return false ;
}
/**
* 验证指定的数据是否为null或者是“""”
* @return 如果是空字符串则返回false,否则返回true
*/
public static boolean validateEmpty(String val) {
if (val == null || "".equals(val)) {
return false ;
}
return true ;
}
}
可以根据指定的资源名称和指定的key取得对应的value内容
package cn.mldn.util;
import java.util.ResourceBundle;
public class ResourceUtils {
/**
* 可以根据指定的资源名称和指定的key取得对应的value内容
* @param baseName
* @param key
* @return
*/
public static String get(String baseName, String key) {
return ResourceBundle.getBundle(baseName).getString(key) ;
}
}
实现字符串的首字母大写处理
package cn.mldn.util;
public class StringUtils {
/**
* 实现字符串的首字母大写处理
* @param str
* @return
*/
public static String initcap(String str) {
if (str == null || "".equals(str)) {
return str ;
}
if (str.length() == 1) {
return str.toUpperCase() ;
}
return str.substring(0,1).toUpperCase() + str.substring(1) ;
}
}
package cn.mldn.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
arg0.setCharacterEncoding("UTF-8");
arg1.setCharacterEncoding("UTF-8");
arg2.doFilter(arg0, arg1);
}
}
package cn.mldn.vo;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Dept implements Serializable {
private Integer deptno ;
private String dname ;
private Company company ;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
@Override
public String toString() {
return "\n\tDept [deptno=" + deptno + ", dname=" + dname + ", company=" + company + "]";
}
}
package cn.mldn.vo;
public class Company {
private String cname ;
private String address ;
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "\n\tCompany [cname=" + cname + ", address=" + address + "]";
}
}
package cn.mldn.vo;
import java.io.Serializable;
import java.util.Date;
@SuppressWarnings("serial")
public class Emp implements Serializable {
private Integer empno ;
private String ename ;
private Double sal ;
private Date hiredate ;
private Dept dept ;
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
return "Emp [empno=" + empno + ", ename=" + ename + ", sal=" + sal + ", hiredate=" + hiredate + ", dept=" + dept
+ "]";
}
}