day51_电力系统_用户管理

项目第四天(用户管理)

1:需要的表

day51_电力系统_用户管理_第1张图片

day51_电力系统_用户管理_第2张图片

这里一个用户对应多个用户职称附件,所有用户表和用户职称附件表是一个一对多的关系。

2:项目中配置hibernate一对多的关系

一对一端
(1)ElecUser.java
day51_电力系统_用户管理_第3张图片

(2)ElecUser.hbm.xml
day51_电力系统_用户管理_第4张图片

多的一端

(3)ElecUserFile.java
day51_电力系统_用户管理_第5张图片

(4)ElecUserFile.hbm.xml
这里写图片描述

3:jquery的ajax实现二级联动

(1)页面效果:
day51_电力系统_用户管理_第6张图片

(2)操作步骤:
第一步:引入struts整合json的插件包
这里写图片描述
第二步:在struts.xml中定义:
修改:

<package name="system" namespace="/system" extends="struts-default">

修改成

<package name="system" namespace="/system" extends="json-default">

在Action中添加:

<result name="findJctUnit" type="json">result>

第三步:页面使用jquery的ajax调用二级联动的js

//ajax的二级联动,使用选择的所属单位,查询该所属单位下对应的单位名称列表
    function findJctUnit(o){
        //货物所属单位的文本内容
        var jct = $(o).find("option:selected").text();
        $.post("elecUserAction_findJctUnit.do",{"jctID":jct},function(data,textStatus){
            //先删除单位名称的下拉菜单,但是请选择要留下
            $("#jctUnitID option").remove();
            if(data!=null && data.length>0){
                for(var i=0;ivar ddlCode = data[i].ddlCode;
                    var ddlName = data[i].ddlName;
                    //添加到单位名称的下拉菜单中
                    var $option = $("");
                    $option.attr("value",ddlCode);
                    $option.text(ddlName);
                    $("#jctUnitID").append($option);
                }
            }
        });

    }

第四步:在Action中定义,这里要将返回的List集合放置到栈顶,struts2将其转换成json数据:例如:

public String findJctUnit(){
        //1:传递所属单位对应的名称,以名称作为条件,查询数据字典,返回List
        String jctID = elecUser.getJctID();
        List<ElecSystemDDL> list = elecSystemDDLService.findSystemDDLListByKeyword(jctID);
        //2:将List转化成json数据,并返回到页面上
        //将list压入到struts2值栈的栈顶,struts2的插件包,将结果转换成json数据
        ValueStackUtils.setValueStack(list);
        return "findJctUnit";
    }

上面的操作,将栈顶中封装的List集合,其中List集合中的对象所有的属性全部被json化。
总结:将List中存放的对象中的所有属性全部被json化,如果想针对某个属性被json化
此时可以修改struts.xml文件:
添加:


    <result name="findJctUnit" type="json">
        <param name="includeProperties">\[\d+\]\.ddlCode,\[\d+\]\.ddlNameparam>
    result>

4:jquery的ajax实现登录名的校验

(1)页面效果:
鼠标失去焦点时,页面会进行校验。
这里写图片描述

(2)操作步骤:
第一步:引入插件包
这里写图片描述
第二步:在struts.xml中定义:
修改:

<package name="system" namespace="/system" extends="struts-default">

修改成

<package name="system" namespace="/system" extends="json-default">

在struts.xml中添加:

<result name="checkUser" type="json">
        
        <param name="root">messageparam>
        
        <param name="includeProperties">messageparam>
result>

第三步:页面的写法

/**校验登录名是否出现重复*/
    function checkUser(o){
        //alert(o.value);//dom的写法
        //alert($(o).val());//jquery的写法
        var logonName = $(o).val();
        //以登录名作为查询条件,查询该登录名是否在数据库表中存在记录
        $.post("elecUserAction_checkUser.do",{"logonName":logonName},function(data){
            //如果栈顶是模型驱动的对象,取值的时候应该使用data.message的方式
            //如果栈顶是模型驱动的对象的某个属性,取值的时候应该使用data即可
                 if(data==1){
                $("#check").html("登录名不能为空");
                o.focus();
                $("#BT_Submit").attr("disabled","none");
            }
            else if(data==2){
                $("#check").html("登录名已经存在");
                $(o)[0].focus();
                $("#BT_Submit").attr("disabled","none");
            }
            else{
                $("#check").html("登录名可以使用");
                $("#BT_Submit").attr("disabled","");
            }
        });
    }

第四步:在Action类的代码中定义:将String类型的message放置到栈顶:例如

public String checkUser(){
        //1:获取页面传递的登录名,以登录名作为条件,查询用户表,返回message
        String logonName = elecUser.getLogonName();
        /**
         *     如果message==1,说明登录名为空,此时不能执行保存
               如果message==2,说明登录名在数据库表中已经存在记录(list.size()>0),此时不能执行保存
               如果message==3,说明登录名在数据库表中不存在记录(list.size()==0),此时可以执行保存
         */
        String message = elecUserService.checkUserByLogonName(logonName);
        //将标识message的值放置到栈顶的对象,返回到页面上
        elecUser.setMessage(message);
        return "checkUser";
    }

第五步:在Service类的代码中查询message标识的值

public String checkUserByLogonName(String logonName) {
        String message = "";
        if(StringUtils.isNotBlank(logonName)){
            String condition = " and o.logonName=?";
            Object [] params = {logonName};
            //查询获取用户信息
            List list = elecUserDao. onditionNoPage(condition, params, null);
            if(list!=null && list.size()>0){ findCollectionByC
                message = "2";
            }
            else{
                message = "3";
            }
        }
        else{
            message = "1";
        }
        return message;
}

5:正则表达式的使用(js)页面:

if(checkNull(theForm.contactTel)){
         if(!checkPhone(theForm.contactTel.value))
          {
            alert("请输入正确的电话号码");
            theForm.contactTel.focus();
            return false;
          }
        }

Js中定义:function checkPhone(strNumber)

{
    var pattern = /(^[0-9]{3,4}\-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^\([0-9]{3,4}\)[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/;
    if(pattern.test(strNumber))return true;
    return false;
}

大家只要知道正则表达式的用法,具体校验看项目中的要求(可以通过网络查询,获取到大家想要的表达式的写法)

6:文件上传

多文件上传的要求:
1:完成文件上传
1:将上传的文件统一放置到upload的文件夹下
2:将每天上传的文件,使用日期格式的文件夹分开,将每个业务的模块放置统一文件夹下
3:上传的文件名要指定唯一,可以使用UUID的方式,也可以使用日期作为文件名
4:封装一个文件上传的方法,该方法可以支持多文件的上传,即支持各种格式文件的上传
5:保存路径path的时候,使用相对路径进行保存,这样便于项目的可移植性

第一步:在util包下封装一个方法:

public class FileUploadUtils {

    //完成文件上传,同时返回上传文件的路径path(相对路径)
    /**
     * 完成文件上传
          1:将上传的文件统一放置到upload的文件夹下
          2:将每天上传的文件,使用日期格式的文件夹分开,并使得每个业务模块用文件夹的方式分开
          3:上传的文件名要指定唯一,可以使用UUID的方式,也可以使用日期作为文件名
          4:封装一个文件上传的方法,该方法可以支持多文件的上传,即支持各种格式文件的上传
          5:保存路径path的时候,使用相对路径进行保存,这样便于项目的可移植性

     */
    public static String fileUploadReturnPath(File upload, String uploadFileName,String model) {
        //获取upload的文件夹
        String basepath = ServletActionContext.getServletContext().getRealPath("/upload");
        //指定日期格式的文件夹(yyyy/MM/dd)
        String datepath = DateUtils.dateToString(new Date());
        //文件后缀
        String perfix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
        //文件名(格式:ADFSDFSDFA@#$@#[email protected])
        String filename = UUID.randomUUID().toString()+perfix;

        //判断当前日期文件夹是否存在,如果不存在,创建一个日期的文件夹
        String modelPath = basepath+datepath+model;
        File dateFile = new File(modelPath);
        if(!dateFile.exists()){
            dateFile.mkdirs();
        }

        //目标文件
        File destFile = new File(modelPath+"/"+filename);   
        //文件上传
        upload.renameTo(destFile);
        //返回相对路径
        return "/upload"+ datepath+model+"/"+filename;
    }
    public static void main(String[] args) throws Exception {
        //文件上传
        //方案一:(复制,粘贴)
        //源文件
        File srcFile = new File("F:\\dir\\a.txt");
        //目标文件
        File destFile = new File("F:\\dir\\dir2xxxxxxxxxxx\\a.txt");
        //FileUtils.copyFile(srcFile, destFile);

        //方案二:(剪切)
        boolean flag = srcFile.renameTo(destFile);
        System.out.println(flag);
    }

}

第二步:jsp页面的表单要求:
并且表单提交:

name="Form1" action="${pageContext.request.contextPath }/workflow/elecApplicationTemplateAction_save.do" method="post" enctype="multipart/form-data"> file name="upload" id="upload" cssStyle="width:450px;">file> *

第三步:文件上传的要求:
在VO对象中:

//获取文件类型的upload
    private File [] upload;
    //文件类型
    private String [] uploadContentType;
    //文件名
    private String [] uploadFileName;

其中upload表示页面提交的文件:
uploadContentType表示获取上传文件的类型
uploadFileName表示获取上传文件的名称

file name="upload" id="upload" cssStyle="width:450px;">file> *

这里注意:如果是单文件上传,就是File类型的对象
如果是多文件上传,就是File类型的数组对象

7:文件下载

页面效果:
day51_电力系统_用户管理_第7张图片
(1)不使用struts2提供的文件下载
Action类的处理代码:

public String download() throws Exception{
        //1:获取用户附件ID,查询用户附件对象,获取路径path
        String id = elecUser.getFileID();
        ElecUserFile elecUserFile = elecUserService.findElecUserFileByID(id);
        //路径path
        String path = elecUserFile.getFileURL();
        //下载时,使用的文件名
        String name = elecUserFile.getFileName();
        //处理中文问题,或者使用:name = URLEncoder.encode(name, "UTF-8");
        name = new String(name.getBytes("gbk"),"iso-8859-1");
        //2:使用response对象设置文件下载的信息(头部信息,文件类型…)
        response.setHeader("Content-disposition", "attachment;filename="+name+"");
        response.setBufferSize(1024);
        //3:使用InputStream输入流读到path路径下对应文件,将InputStream的输入流写到输出流(response对象中获取)中
        InputStream in = new FileInputStream(new File(ServletActionContext.getServletContext().getRealPath("")+path));
        OutputStream out = response.getOutputStream();
        for(int b=-1;(b=in.read())!=-1;){
            out.write(b);
        }
        out.close();
        in.close();
        return null;
    }

(2)使用struts2提供的文件下载

第一步:配置struts.xml
这里写图片描述
第二步:在模型驱动的对象中,添加InputStream类型的属性,用来存放文件的输入流
其中属性名称要与struts.xml中定义的inputName的值一致。
day51_电力系统_用户管理_第8张图片
第三步:将查询的文件输入流放置到模型驱动定义的inputStream属性中,用来输出文件。

第四步:Action类中代码:

public String download() throws Exception{
        String id = elecUser.getFileID();
        ElecUserFile elecUserFile = elecUserService.findElecUserFileByID(id);
        //路径path
        String path = elecUserFile.getFileURL();
        //下载时,使用的文件名
        String name = elecUserFile.getFileName();
        //处理中文问题,或者使用:name = URLEncoder.encode(name, "UTF-8");
        name = new String(name.getBytes("gbk"),"iso-8859-1");
        request.setAttribute("filename", name);

        //2:使用InputStream输入流读到path路径下对应文件
        InputStream in = new FileInputStream(new File(ServletActionContext.getServletContext().getRealPath("")+path));
        //将输入流压入到栈顶
        elecUser.setInputStream(in);
        return "fileSuccess";
    }

8:使用md5的密码加密,处理用户的密码

需求:
day51_电力系统_用户管理_第9张图片

操作步骤:
第一步:导入工具类,放置到cn.itcast.elec.util包下
这里写图片描述
第二步:在保存用户和更新用户的前添加一个方法(md5Password):

private void md5Password(ElecUser elecUser) {
        //加密前
        String logonPwd = elecUser.getLogonPwd();
        //加密后
        String md5LogonPwd = "";
        if(StringUtils.isBlank(logonPwd)){
            logonPwd = "123";
        }
        //获取加密前的密码
        String password = elecUser.getPassword();
        //加密前的密码与输入的密码相等:说明没有修改密码
        if(StringUtils.isNotBlank(password) && password.equals(logonPwd)){
            md5LogonPwd = logonPwd;
        }
        else{
            //使用MD5进行密码加密
            MD5keyBean md5keyBean = new MD5keyBean();
            md5LogonPwd = md5keyBean.getkeyBeanofStr(
            logonPwd);
        }
        //将加密后的结果放置到ElecUser对象中
        elecUser.setLogonPwd(md5LogonPwd);
    }

其中password属性表示在编辑用户页面(userEdit.jsp)传递的数据库中存放的密码,用来判断是否在编辑用户的时候修改了密码:添加一个隐藏域实现,隐藏域中存放页面修改之前密码的值

<s:hidden name="password" value="%{logonPwd}">s:hidden>

9:需要掌握的知识点总结

重点:用户管理开发,熟练使用jquery的ajax完成业务操作,文件的上传和下载
方案一:使用URL存放路径
方案二:数据库中使用Blob字段,参考:
day51_电力系统_用户管理_第10张图片
了解知识:md5的密码加密

你可能感兴趣的:(黑马培训班)