1.新建项目,添加jar包

  tomcat

  jsp

  struts、hibernate、spring

2.配置

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!--配置spring监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--配置struts核心过滤器-->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <!-- 禁用动态方法访问!userAction -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <!-- 配置成开发模式 -->
    <constant name="struts.devMode" value="true" />
    <!-- 配置拓展名为action -->
    <constant name="struts.action.extention" value="action" />
    <!-- 把主题配置成simple -->
    <constant name="struts.ui.theme" value="simple" />
</struts>

3.测试spring

创建测试类TestService,并使用注解方式加入容器;

创建测试配置文件test-spring.xml(开启注解扫描)

<context:component-scan base-package="com.juaner.test.service.impl"></context:component-scan>

在主配置文件中引入配置文件

<import resource="classpath:com/juaner/*/conf/*-spring.xml"/>

测试spring

    @Test
    public void testSpring(){
        TestService ts= (TestService) ct.getBean("testService");
        ts.say();
    }

4.测试struts-spring

创建action,注入testService,并调用方法;

配置test-struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="test-action" namespace="/" extends="struts-default">
        <action name="test_*" class="com.juaner.test.action.TestAction" method="{1}">
            <result name="success">/WEB-INF/jsp/test/test.jsp</result>
        </action>
    </package>
</struts>

在struts.xml中引入配置文件

    <include file="com/juaner/test/conf/test-struts.xml"/>

访问action

5.测试hibernate-spring

配置数据源

    <!-- 导入外部的properties配置文件 -->
    <context:property-placeholder location="classpath:db.properties" />

    <!-- 配置c3p0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
        <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize" value="${initialPoolSize}"></property>
        <!--连接池中保留的最小连接数。Default: 3 -->
        <property name="minPoolSize" value="3"></property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="${maxPoolSize}"></property>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3"></property>
        <!--最大空闲时间,1800秒内未使用则连接被丢弃,若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800"></property>
    </bean>

配置db.properties

jdbcUrl=jdbc:mysql://localhost:3306/itcastTax?useUnicode=true&characterEncoding=utf8
driverClass=com.mysql.jdbc.Driver
user=root
password=juaner767
initialPoolSize=10
maxPoolSize=30

新建实例类Person及相应的配置文件person.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.juaner.test.entity.Person" table="person">
        <id name="id" type="java.lang.String">
            <column name="id" length="32" />
            <generator class="uuid" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="20" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

配置hibernate sessionfactory属性及映射文件

    <bean id="sf" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="javax.persistence.validation.mode">none</prop>
            </props>
        </property>
        <property name="mappingLocations">
            <list>
                <value>classpath:com/juaner/test/entity/*.hbm.xml</value>
            </list>
        </property>
    </bean>

测试hibernate

    ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
    @Test
    public void testHibernate(){
        SessionFactory sf = (SessionFactory) ct.getBean("sf");
        Session session = sf.openSession();
        Transaction transaction = session.beginTransaction();

        session.save(new Person("人员1"));

        transaction.commit();
        session.close();
    }

6.事务控制

配置事务

    <!--事务管理-->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf"/>
    </bean>
    <!--事务增强-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="list*" read-only="true"/>
            <tx:method name="search*" read-only="true"/>
            <tx:method name="*" rollback-for="Throwable" />
        </tx:attributes>
    </tx:advice>
    <!--aop-->
    <aop:config>
        <aop:pointcut id="serviceOperation" expression="bean(*Service)"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
    </aop:config>

    <bean id="testDao" class="com.juaner.test.dao.impl.TestDaoImpl">
        <property name="sessionFactory" ref="sf"/>
    </bean>

开发TestDao、TestService接口及其实现类

public class TestDaoImpl extends HibernateDaoSupport implements TestDao{

    @Override
    public void save(Person person) {
        getHibernateTemplate().save(person);
    }

    @Override
    public Person findPerson(Serializable id) {
        return getHibernateTemplate().get(Person.class,id);
    }
}
    <bean id="testDao" class="com.juaner.test.dao.impl.TestDaoImpl">
        <property name="sessionFactory" ref="sf"/>
    </bean>

 

@Service("testService")
public class TestServiceImpl implements TestService{
    @Resource
    private TestDao testDao;
    @Override
    public void say() {
        System.out.println("hi");
    }

    @Override
    public void save(Person person) {
        testDao.save(person);
    }

    @Override
    public Person findPerson(Serializable id) {
        return testDao.findPerson(id);
    }
}

测试:必须用TestService接口接收,不能用TestServiceImpl接收,因为TestServiceImpl实现了TestService接口,生成的代理类也是TestService的子类,无法转成TestServiceImpl

    @Test
    public void testReadOnly(){
        TestService testService= (TestService) ct.getBean("testService");
        System.out.println(testService.findPerson("fd5872945599fd07015599fd08580000").getName());
    }

    @Test
    public void testRollBack(){
        TestService testService= (TestService) ct.getBean("testService");
        testService.save(new Person("人员4"));
    }

7.资源分类

8.配置log4j

导入jar包

配置log4j.xml

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p [%t] %c{1}:%L - %m%n


log4j.rootLogger=error, stdout,R
#log4j.logger.com.juaner=error

log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=/itcastTax.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d [%t] %5p  %c - %m%n

9.用户的增删改查

抽取BaseDao

BaseDao、BaseDaoImpl

public interface BaseDao<T> {
    public void save(T entity);
    public void delete(Serializable id);
    public void update(T entity);
    public T findObjectById(Serializable id);
    public List<T> findObjects();
}

反射

public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{
    private Class<T> clazz;

    public BaseDaoImpl(){
        //获取被实例化的类泛型 BaseDaoImpl<User>=
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        clazz = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public void save(Object entity) {
        getHibernateTemplate().save(entity);
    }

    @Override
    public void delete(Serializable id) {
        getHibernateTemplate().delete(findObjectById(id));
    }

    @Override
    public void update(Object entity) {
        getHibernateTemplate().update(entity);
    }

    @Override
    public T findObjectById(Serializable id) {
        return getHibernateTemplate().get(clazz,id);
    }

    @Override
    public List<T> findObjects() {
        Session session = getSession();
        Query query = session.createQuery("from "+clazz.getSimpleName());
        return query.list();
    }
}

User实体类及映射

public class User {
    private String id;
    private String dept;
    private String name;
    private String account;
    private String password;
    //头像
    private String headImg;
    private boolean gender;
    private String state;
    private String mobile;
    private String email;
    private Date birthday;
    private String memo;
    set...
    get...
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.juaner.nsfw.user.entity.User" table="user">
        <id name="id" type="java.lang.String">
            <column name="id" length="32" />
            <generator class="uuid" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="20" not-null="true" />
        </property>
        <property name="dept" type="java.lang.String">
            <column name="dept" length="20" not-null="true" />
        </property>        
        <property name="account" type="java.lang.String">
            <column name="account" length="50" not-null="true" />
        </property>
        <property name="password" type="java.lang.String">
            <column name="password" length="50" not-null="true" />
        </property>
        <property name="headImg" type="java.lang.String">
            <column name="headImg" length="100" />
        </property>
        <property name="gender" type="java.lang.Boolean">
            <column name="gender" />
        </property>
        <property name="email" type="java.lang.String">
            <column name="email" length="50" />
        </property>
        <property name="mobile" type="java.lang.String">
            <column name="mobile" length="20" />
        </property>
        <property name="birthday" type="java.util.Date">
            <column name="birthday" length="10" />
        </property>
        <property name="state" type="java.lang.String">
            <column name="state" length="1" />
        </property>
        <property name="memo" type="java.lang.String">
            <column name="memo" length="200" />
        </property>
    </class>

</hibernate-mapping>

UserDao、UserDaoImpl

public interface UserDao extends BaseDao<User> {
}
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{
}

UserService、UserServiceImpl

public interface UserService {
    public void save(User user);
    public void delete(Serializable id);
    public void update(User user);
    public User findObjectById(Serializable id);
    public List<User> findObjects();
}
@Service("userService")
public class UserServiceImpl implements UserService{
    @Resource
    private UserDao userDao;
    @Override
    public void save(User user) {
        userDao.save(user);
    }

    @Override
    public void delete(Serializable id) {
        userDao.delete(id);
    }

    @Override
    public void update(User user) {
        userDao.update(user);
    }

    @Override
    public User findObjectById(Serializable id) {
        return userDao.findObjectById(id);
    }

    @Override
    public List<User> findObjects() {
        return userDao.findObjects();
    }
}

user-spring配置

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <bean id="userDao" class="com.juaner.nsfw.user.dao.impl.UserDaoImpl" parent="baseDao">
    </bean>
    <context:component-scan base-package="com.juaner.nsfw.user.conf"/>
</beans>

其中,baseDao在spring的主配置文件中配置,这样可以避免为sf的更改带来dao的大量改变。

    <bean id="baseDao" abstract="true">
        <property name="sessionFactory" ref="sf"/>
    </bean>

UserAction及struts配置

 注意:add方法之后跳转需要重定向地址,但是listUI位于WEB-INF下,而且需要重新查询所有的user,所以需要redirectAction,调用listUI方法。

public class UserAction extends ActionSupport{
    //IOC容器根据名称查询是否存在叫userService的bean,然后赋值
    //所以必须叫userService,否则出错
    @Resource
    private UserService userService;
    private List<User> userList;
    private User user;


    /**
     * 新增:跳转
     */
    public String addUI(){
        return "addUI";
    }
    /**
     *新增:增加
     */
    public String add(){
        if(user != null)
            userService.save(user);
        return SUCCESS;
    }
    /**
     *删除:删除一个
     */
    public String delete(){
        if(user != null && user.getId()!= null)
            userService.delete(user.getId());
        return SUCCESS;
    }
    /**
     *删除:批量删除
     */
    public String deleteSelected(){
        return SUCCESS;
    }
    /**
     *修改:跳转
     */
    public String editUI(){
        return "editUI";
    }
    /**
     *修改:修改
     */
    public String edit(){
        if(user != null && user.getId()!= null)
            userService.update(user);
        return SUCCESS;
    }
    /**
     *查询
     */
    public String listUI(){
        userList = userService.findObjects();
        return "listUI";
    }
    get...
    set...
}

user-struts.xml

<struts>
    <package name="user-action" extends="struts-default" namespace="/nsfw">
        <global-results>
            <result name="success">/WEB-INF/jsp/nsfw/user/listUI.jsp</result>
        </global-results>
        <action name="user_*" class="com.juaner.nsfw.user.action.UserAction" method="{1}">
            <result name="{1}">/WEB-INF/jsp/nsfw/user/{1}.jsp</result>
        </action>
    </package>
</struts>

struts iterator标签

  <s:iterator value="userList" status="st">
    <tr <s:if test="#st.odd"> bgcolor="f8f8f8"</s:if>>
     <td align="center"><input type="checkbox" name="selectedRow" value="<s:property value="id" />"/></td>
     <td align="center"><s:property value="name" /></td>
     <td align="center"><s:property value="account" /></td>
     <td align="center"><s:property value="dept" /></td>
     <td align="center"><s:property value="gender?'男':'女'"/> </td>
     <td align="center"><s:property value="email" /></td>
     <td align="center">
       <a href="javascript:doEdit('<s:property value='id'/>')">编辑</a>
       <a href="javascript:doDelete('<s:property value='id'/>')">删除</a>
     </td>
    </tr>
   </s:iterator>

10.使用datepicker插件

在js中导入WdataPicker,并引入

<script type="text/javascript" src="${basePath}js/datepicker/WdatePicker.js"></script>

使用

<s:textfield id="birthday" name="user.birthday" readonly="true"
                             onfocus="WdatePicker({skin:'whyGreen',dateFmt:'yyyy-MM-dd'})"/>
<s:textfield id="birthday" name="user.birthday" readonly="true"
                             onfocus="WdatePicker({skin:'whyGreen',dateFmt:'yyyy-MM-dd'})">
                       <s:param name="value"><s:date name='user.birthday' format='yyyy-MM-dd' /></s:param>      
            </s:textfield>

11.头像的上传与下载

struts上传文件,需要一个File,contentType,filename。

add.jsp

提交的表单enctype

<form id="form" name="form" action="${basePath}nsfw/user_add.action" method="post" enctype="multipart/form-data">
        <tr>
            <td class="tdBg" width="200px">头像:</td>
            <td>
                <input type="file" name="headImg"/>
            </td>
        </tr>

UserAction方法添加字段及上传方法

    private File headImg;
    private String headImgContentType;
    private String headImgFileName;
    public String add(){
        try {
            if(user != null) {
                if (headImg != null) {
                    //获取保存路径的绝对地址
                    String filePath= ServletActionContext.getServletContext().getRealPath("upload/user");
                    //防止被覆盖需要重命名,中文文件名可能无法正常显示
                    String fileName = UUID.randomUUID().toString().replace("-","")+headImgFileName.substring(headImgFileName.lastIndexOf("."));
                    //复制文件
                    FileUtils.copyFile(headImg,new File(filePath,fileName));
                    //设置用户头像路径
                    user.setHeadImg("user/"+fileName);
                }
                userService.save(user);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "list";
    }

edit.jsp

            <td>
                <s:if test="%{user.headImg != null && user.headImg != ''}">
                    <img src="${basePath}upload/<s:property value='user.headImg'/> " width="100" height="100"/>
                    <%--防止图片丢失--%>
                    <s:hidden name="user.headImg"/>
                </s:if>
                <input type="file" name="headImg"/>
            </td>

12.POI实现excel导入导出

导入和导出按钮设置

        function doImportExcel(){
            document.forms[0].action = "${basePath}nsfw/user_importExcel.action";
            document.forms[0].submit();
        }
        function doExportExcel(){
            window.open("${basePath}nsfw/user_exportExcel2.action");
        }

UserAction中添加方法

    //导出数据
    public void  exportExcel(){
        try {
            users = userService.findObjects();
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setContentType("application/x-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String("用户列表.xls".getBytes(), "ISO-8859-1"));
            ServletOutputStream outputStream = response.getOutputStream();
            userService.exportExcel(outputStream,users);

            if(outputStream != null)
                outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //导入数据
    private File userExcel;
    private String userExcelContentType;
    private String userExcelFileName;

    public String importExcel(){
        if(userExcel != null)
        {
            if(userExcelFileName.matches("^.+\\.(?i)((xls)|(xlsx))$")){
                try {
                    userService.importExcel(userExcel,userExcelFileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "list";
    }

    public File getUserExcel() {
        return userExcel;
    }

    public void setUserExcel(File userExcel) {
        this.userExcel = userExcel;
    }

    public String getUserExcelContentType() {
        return userExcelContentType;
    }

    public void setUserExcelContentType(String userExcelContentType) {
        this.userExcelContentType = userExcelContentType;
    }

    public String getUserExcelFileName() {
        return userExcelFileName;
    }

    public void setUserExcelFileName(String userExcelFileName) {
        this.userExcelFileName = userExcelFileName;
    }

抽取方法到ExcelUtil

public class ExcelUtil {
    public static void exportUserExcel(List<User> userList, ServletOutputStream outputStream) throws Exception{
        HSSFWorkbook workbook = new HSSFWorkbook();
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, 4);

        HSSFCellStyle headStyle = createCellStyle(workbook, (short) 16);
        HSSFCellStyle colStyle = createCellStyle(workbook, (short) 13);

        HSSFSheet sheet = workbook.createSheet("用户列表");
        sheet.addMergedRegion(cellRangeAddress);

        HSSFRow headRow = sheet.createRow(0);
        HSSFCell headCell = headRow.createCell(0);
        headCell.setCellStyle(headStyle);
        headCell.setCellValue("用户列表");

        sheet.setDefaultColumnWidth(25);
        HSSFRow colRow = sheet.createRow(1);
        String[] titles = new String[]{"用户名","账户名","所属部门","性别","电子邮箱"};
        for(int i=0;i<titles.length;i++){
            HSSFCell cell = colRow.createCell(i);
            cell.setCellStyle(colStyle);
            cell.setCellValue(titles[i]);
        }
        if(userList!=null&& userList.size()>0)
        {
            for(int i=0;i<userList.size();i++)
            {
                HSSFRow row = sheet.createRow(i + 2);
                HSSFCell cell1 = row.createCell(0);
                cell1.setCellValue(userList.get(i).getName());
                HSSFCell cell2 = row.createCell(1);
                cell2.setCellValue(userList.get(i).getAccount());
                HSSFCell cell3 = row.createCell(2);
                cell3.setCellValue(userList.get(i).getDept());
                HSSFCell cell4 = row.createCell(3);
                cell4.setCellValue(userList.get(i).isGender()?"男":"女");
                HSSFCell cell5 = row.createCell(4);
                cell5.setCellValue(userList.get(i).getEmail());
            }
        }
        workbook.write(outputStream);
        workbook.close();
    }

    private static HSSFCellStyle createCellStyle(HSSFWorkbook workbook, short fontSize) {
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        HSSFFont headFont = workbook.createFont();
        headFont.setBold(true);
        headFont.setFontHeightInPoints(fontSize);
        style.setFont(headFont);
        return style;
    }
}

给UserService和UserServiceImpl添加方法

   @Override
    public void exportExcel(ServletOutputStream outputStream, List<User> users) throws IOException {
        ExcelUtil.exportUserExcel(outputStream,users);

    }

    @Override
    public void importExcel(File userExcel, String fileName) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(userExcel);
        //判断03或者07
        boolean is03Excel = fileName.matches("^.+\\.(?i)(xls)&");
        Workbook workbook = is03Excel?new HSSFWorkbook(fileInputStream):new XSSFWorkbook(fileInputStream);
        Sheet sheet = workbook.getSheetAt(0);
        if(sheet.getPhysicalNumberOfRows() > 2){
            User user = null;
            for(int i=2;i<sheet.getPhysicalNumberOfRows();i++){
                Row row = sheet.getRow(i);
                String acount = row.getCell(1).getStringCellValue();
                if(isUserExists(acount))
                    continue;
                user = new User();
                user.setName(row.getCell(0).getStringCellValue());
                user.setAccount(row.getCell(1).getStringCellValue());
                user.setDept(row.getCell(2).getStringCellValue());
                user.setGender(row.getCell(3).getStringCellValue().equals("男")?true:false);
//                如果电话用科学计数法,转为string
                String mobile = "";
                try {
                    mobile = row.getCell(4).getStringCellValue();
                }catch (Exception e){
                    double dMobile = row.getCell(4).getNumericCellValue();
                    mobile = BigDecimal.valueOf(dMobile).toString();
                }
                user.setMobile(mobile);
                user.setEmail(row.getCell(5).getStringCellValue());
                user.setBirthday(row.getCell(6).getDateCellValue());
                user.setState(User.USER_STATE_VALID);
                user.setPassword("123456");
                save(user);
            }
        }
        workbook.close();
        fileInputStream.close();

    }

导入数据

action中

    public String importExcel(){
        if(userExcel !=null){
            try {
                if(userExcelFileName.matches("^.+\\.(?i)((xls)|(xlsx))$")){
                    userService.importExcel(userExcel,userExcelFileName);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return SUCCESS;
    }

service中

    public void importExcel(File userExcel, String userExcelFileName) throws Exception {
        boolean is03Excel = userExcelFileName.matches("^.+\\.(?i)(xls)$");
        FileInputStream inputStream = new FileInputStream(userExcel);
        Workbook workbook = is03Excel ? new HSSFWorkbook(inputStream) : new XSSFWorkbook(inputStream);
        Sheet sheet = workbook.getSheetAt(0);
        if(sheet.getPhysicalNumberOfRows()>2){
            for(int i=2;i<sheet.getPhysicalNumberOfRows();i++){
                User user = new User();
                Row row = sheet.getRow(i);
                String name = row.getCell(0).getStringCellValue();
                user.setName(name);
                String account = row.getCell(1).getStringCellValue();
                user.setAccount(account);
                String dept = row.getCell(2).getStringCellValue();
                user.setDept(dept);
                String gender = row.getCell(3).getStringCellValue();
                user.setGender(true);
                String mobile = "";
                try {
                    mobile = row.getCell(4).getStringCellValue();
                }catch (Exception e){
                    double dmobile = row.getCell(4).getNumericCellValue();
                    mobile = BigDecimal.valueOf(dmobile).toString();
                }
                user.setMobile(mobile);
                String email = row.getCell(5).getStringCellValue();
                user.setEmail(email);
                Date birthday = row.getCell(6).getDateCellValue();
                user.setBirthday(birthday);
                user.setPassword("123456");
                user.setState(User.USER_STATE_VALID);
                save(user);
            }
        }
        inputStream.close();
    }

13账号唯一性校验

在增加和修改页面中需要进行账号唯一性校验。编辑页面查找账号唯一性需要先排除正在编辑的用户的账号。

spring提供了StringUtils.isNotBlank来检查字符串。

点击提交按钮后,需要使用ajax同步来验证是否账号唯一。

addUI.jsp

    <script type="text/javascript">
        var result = false;
        function verifyAccount(){
            var account = $("#account").val();
            if(account.trim()=="")
                return ;
            var url = "${basePath}nsfw/user_verifyAccount.action?time="+new Date().getTime();
            var content = {
                "user.account":account
            };
            $.ajax({
                type:"POST",
                url:url,
                data:content,
                async:false,
                success:function(msg) {
                    if ("true" == msg){
                        alert("账号已经存在,请使用其他账号!");
                        $("#account").focus();
                        result = false;
                    }else{
                        result = true;
                    }
                }
            })
        }
        function doSubmit(){
            verifyAccount();
            if(result==true)
                document.forms[0].submit();
        }
    </script>

editUI.jsp

    <script type="text/javascript">
        var result = false;
        function verifyAccount(){
            var account = $("#account").val();
            if(account.trim()=="")
                return ;
            var url = "${basePath}nsfw/user_verifyAccount.action?time="+new Date().getTime();
            var content = {
                "user.account":account,
                "user.id":"${user.id}"
            };
            $.ajax({
                type:"POST",
                url:url,
                data:content,
                async:false,
                success:function(msg) {
                    if ("true" == msg){
                        alert("账号已经存在,请使用其他账号!");
                        $("#account").focus();
                        result = false;
                    }else{
                        result = true;
                    }
                }
            })
        }
        function doSubmit(){
            verifyAccount();
            if(result==true)
                document.forms[0].submit();
        }
    </script>

aciton

    public void verifyAccount() throws IOException {
        HttpServletResponse response = ServletActionContext.getResponse();
        PrintWriter writer = response.getWriter();
        String msg = "false";
        if(user != null && StringUtils.isNotBlank(user.getAccount())){
            int ret = userService.findUserByAccountAndId(user.getAccount(),user.getId());
            if(ret >0){
                msg = "true";
            }
        }
        writer.write(msg);
        writer.flush();
        writer.close();
    }

dao

    public int findUserByAccountAndId(String account,String id) {
        String hql = "from User where account ="+"'"+account+"'";
        if(StringUtils.isNotBlank(id))
            hql+=" and id != "+"'"+id+"'";
        List list = getSession().createQuery(hql).list();
        return list.size();
    }

14.异常和返回结果类型

15.角色与权限

角色与权限是多对多的关系。但是由于权限没有对应的实体和表,是固定的5个值,所以角色和角色权限(中间表)是一对多的关系。RolePrivilege只有一个属性RolePrivilegeId,RolePrivilegeId作为联合主键类,必须要实现Serializable接口并且重写hashcode和equals方法。

Role

public class Role {
    private String roleId;
    private String name;
    private String state;
    private Set<RolePrivilege> rolePrivileges;
    public static String ROLE_STATE_VALID = "1";
    public static String ROLE_STATE_INVALID = "0";
    get...
    set...
}

Role.hbm.xml

<hibernate-mapping>
    <class name="com.juaner.nsfw.role.entity.Role" table="t_role">
        <id name="roleId" type="java.lang.String">
            <column name="r_id" length="32"/>
            <generator class="uuid"/>
        </id>
        <property name="name" type="java.lang.String">
            <column name="r_name" length="20" not-null="true"/>
        </property>
        <property name="state" type="java.lang.String">
            <column name="r_state" length="1"/>
        </property>
        <set name="rolePrivileges" inverse="true" lazy="false" cascade="save-update,delete">
            <key>
                <column name="r_id" />
            </key>
            <one-to-many class="com.juaner.nsfw.role.entity.RolePrivilege"/>
        </set>
    </class>

</hibernate-mapping>

RolePrivilege

public class RolePrivilege implements Serializable{
    private RolePrivilegeId id;
    get...
    set...
}

RolePrivilegeId

public class RolePrivilegeId implements Serializable{
    private String code;
    private Role role;
    get...
    set...
    equals...
    hashcode...
}

RolePrivilege.hbm.xml

<hibernate-mapping>
    <class name="com.juaner.nsfw.role.entity.RolePrivilege" table="t_roleprivilege">
        <composite-id name="id" class="com.juaner.nsfw.role.entity.RolePrivilegeId">
            <key-many-to-one name="role" lazy="false" class="com.juaner.nsfw.role.entity.Role">
                <column name="r_id"/>
            </key-many-to-one>
            <key-property name="code" type="java.lang.String">
                <column name="p_code" length="20"/>
            </key-property>
        </composite-id>
    </class>
</hibernate-mapping>

跳转到添加页面和修改页面都要在域中设置权限map

    public String addUI(){
        ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);
        return "addUI";
    }

添加角色

    public String add()throws Exception{
        if(role != null){
            if(privilegeIds!=null){
                Set<RolePrivilege> set = new HashSet<>();
                for(String code:privilegeIds){
                    set.add(new RolePrivilege(new RolePrivilegeId(code,role)));
                }
                role.setRolePrivileges(set);
            }
            roleService.save(role);
        }
        return SUCCESS;
    }

跳转到修改页面

    public String editUI(){
        if(role != null && role.getRoleId()!= null) {
            role = roleService.findObjectById(role.getRoleId());
            ActionContext.getContext().getContextMap().put("privilegeMap", Constant.PRIVILEGE_MAP);
            if(role.getRolePrivileges().size()>0){
                privilegeIds = new String[role.getRolePrivileges().size()];
                int i=0;
                for(RolePrivilege roleprivilege:role.getRolePrivileges()){
                    privilegeIds[i++] = roleprivilege.getId().getCode();
                }
            }
        }
        return "editUI";
    }

修改角色,在设置新的权限之前要删掉旧的权限

    public String edit()throws Exception{
        if(role != null && role.getRoleId()!= null){
            if(privilegeIds!=null){
                Set<RolePrivilege> set = new HashSet<>();
                for(String code:privilegeIds){
                    set.add(new RolePrivilege(new RolePrivilegeId(code,role)));
                }
                role.setRolePrivileges(set);
            }
            roleService.update(role);
        }
        return SUCCESS;
    }

16.struts标签

遍历显示

<s:iterator value="roleList" status="st">
    <tr  <s:if test="#st.odd"> bgcolor="f8f8f8"</s:if>>
        <td align="center"><input type="checkbox" name="selectedRow" value="<s:property value='roleId' />"/></td>
        <td align="center"><s:property value="name" /> </td>
        <td align="center">
            <s:iterator value="rolePrivileges">
                <s:property value="#privilegeMap[id.code]"/>
            </s:iterator>
        </td>
        <td align="center"><s:property value="state='1'?'有效':'无效'" /></td>
        <td align="center">
            <a href="javascript:doEdit('<s:property value='roleId' />')">编辑</a>
            <a href="javascript:doDelete('<s:property value='roleId' />')">删除</a>
        </td>
    </tr>
</s:iterator>

checkboxlist

<s:checkboxlist list="#privilegeMap" name="privilegeIds"></s:checkboxlist>

 17.用户角色

  用户类和角色类及其映射都无法再修改,所以需要将用户类和中间表类独立出来。用户和角色是多对多的关系。所以只要创建作为中间表的UserRole,它具有联合主键性质。因为可能有根据用户查询角色的需求,没有根据角色查询用户的需求,所以联合主键类的设计如下:

添加

<s:checkboxlist list="#roleList" name="userRoleIds" listKey="roleId" listValue="name"></s:checkboxlist>

添加用户角色关系时,虽然联合主键类中的对象是Role,但表中实际保存的是roleId,所以不需要查询出响应的Role,只要保存有roleId属性的Role就可以了。虽然保存时user的id属性不存在,但是hibernate在save或update方法之后会对user的其他属性进行回填,所以在save后可以使用id属性。

service

    public void saveUserAndRole(User user, String... userRoleIds) {
        save(user);
        System.out.println(user.getId());
        for(String roleId:userRoleIds){
            UserRole userRole = new UserRole();
            Role role = new Role(roleId);
            userRole.setId(new UserRoleId(role,user.getId()));
            userDao.saveUserRole(userRole);
        }
    }

修改时,跳转到修改页面之前,需要在域对象中放置当前用户的角色

    public String editUI(){
        ActionContext.getContext().getContextMap().put("roleList",roleService.findObjects());
        if(user != null && user.getId()!= null) {
            user = userService.findObjectById(user.getId());
            List<UserRole> userRoles = userService.getUserRolesByUserId(user.getId());
            if(userRoles!=null&&userRoles.size()>0){
                userRoleIds = new String[userRoles.size()];
                int i=0;
                for(UserRole userRole:userRoles){
                    userRoleIds[i++] = userRole.getId().getRole().getRoleId();
                }
            }
        }
        return "editUI";
    }

修改时,需要先删除旧的角色,再添加新的角色

    public void updateUserAndRole(User user, String... userRoleIds) {
        update(user);
        userDao.deleteUserRoleByUserId(user.getId());
        for(String roleId:userRoleIds){
            UserRole userRole = new UserRole();
            Role role = new Role(roleId);
            userRole.setId(new UserRoleId(role,user.getId()));
            userDao.saveUserRole(userRole);
        }
    }

 18.异常

对特定异常类的结果映射,其他action的映射需要继承base-default

对实现了StrutsResultSupport的类的结果映射(配置了对该类的结果映射名后,如果某个action方法返回该映射名,会由该类的doExecute()方法进行处理)。

public class SysResultAction extends StrutsResultSupport {
    @Override
    protected void doExecute(String s, ActionInvocation actionInvocation) throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        BaseAction action = (BaseAction) actionInvocation.getAction();
        System.out.println("进入了SysResultAction......");
    }
}
    <package name="base-default" extends="struts-default">
        <result-types>
            <result-type name="errorAction" class="com.juaner.core.action.SysResultAction"></result-type>
        </result-types>
        <global-results>
            <result name="errorAction" type="errorAction">/WEB-INF/jsp/error.jsp</result>
            <result name="error">/WEB-INF/jsp/error.jsp</result>
            <result name="input">/WEB-INF/jsp/error.jsp</result>
        </global-results>
        <global-exception-mappings>
            <exception-mapping exception="com.juaner.core.exception.ActionException" result="error"></exception-mapping>
            <exception-mapping exception="java.lang.Exception" result="input"></exception-mapping>
        </global-exception-mappings>
    </package>

 

 posted on 2016-08-20 14:51  十三弦  阅读(659)  评论(0编辑  收藏  举报