调查统计系统——参与调查与答案的保存

 

package cn.itcast.surveypark.domain;

import java.util.Date;

/**
 * Answer
 */
public class Answer extends BaseEntity {
    private static final long serialVersionUID = -8578944801066469831L;
    private Integer id;
    private String answerIds;// 选项的索引.(单选存0|1|2, 多选存0,1,2)
    private String otherAnswer;
    private String uuid;// 批次.(没有使用用户id,由于同一个用户可以做N次调查,所以用批次代表某张调查)
    private Date answerTime;

    private Integer questionId;// 关联字段
    private Integer surveyId;// 关联字段(冗余)

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAnswerIds() {
        return answerIds;
    }

    public void setAnswerIds(String answerIds) {
        this.answerIds = answerIds;
    }

    public String getOtherAnswer() {
        return otherAnswer;
    }

    public void setOtherAnswer(String otherAnswer) {
        this.otherAnswer = otherAnswer;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public Date getAnswerTime() {
        return answerTime;
    }

    public void setAnswerTime(Date answerTime) {
        this.answerTime = answerTime;
    }

    public Integer getQuestionId() {
        return questionId;
    }

    public void setQuestionId(Integer questionId) {
        this.questionId = questionId;
    }

    public Integer getSurveyId() {
        return surveyId;
    }

    public void setSurveyId(Integer surveyId) {
        this.surveyId = surveyId;
    }

}
answer.java
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>参与调查</title>
        <link rel="stylesheet" type="text/css" href='<s:url value="/styles.css"/>'>
    </head>
    <body>
        <s:include value="/header.jsp" />
        <s:form action="EngageSurveyAction_doEngageSurvey" method="post" >
            <s:hidden name="currPid" value="%{currPage.id}" />
            <table>
                <tr>
                    <td colspan="2" class="tdWhiteLine"></td>
                </tr>
                <tr>
                    <!-- 输出调查标题 -->
                    <td colspan="2" class="tdHeader"><s:property value="#session.current_survey.title" /></td>
                </tr>
                <tr>
                    <td colspan="2" class="tdWhiteLine"></td>
                </tr>
                <tr>
                    <!-- 页面标题 -->
                    <td colspan="2" class="tdPHeaderL"><s:property value="currPage.title" /></td>
                </tr>
                <tr>
                    <td width="30px"></td>
                    <td>
                        <table>
                            <!-- 遍历问题集合 -->
                            <s:iterator var="q" value="currPage.questions">
                                <!-- 设置变量,对问题的id进行保持 -->
                                <s:set var="qId" value="#q.id" />
                                <!-- 设置变量,保持问题的题型 -->
                                <s:set var="qt" value="#q.questionType" />
                                <tr>
                                    <td class="tdQHeaderL"><s:property value="#q.title"/></td>
                                </tr>
                                <tr>
                                    <td class="tdOptionArea">
                                        <!-- 判断当前题型是否属于前四种 -->
                                        <s:if test='#qt lt 4'>
                                            <s:iterator var="option" value="#q.optionArr" status="st">
                                                <input type='<s:property value="#qt<2?'radio':'checkbox'" />'
                                                       name='q<s:property value="#qId" />'
                                                       value='<s:property value="#st.index" />'
                                                       <s:property value="setTag('q' + #qId,#st.index,'checked')" />
                                                       >
                                                <s:property />
                                                <s:if test="#qt == 1 || #qt == 3"><br></s:if>
                                            </s:iterator>
                                            <!-- 处理'其它'项内容,判断是否含有其他选项 -->
                                            <s:if test="#q.other">
                                                <input type='<s:property value="#qt<2?'radio':'checkbox'" />' 
                                                        name='q<s:property value="#qId"/>' 
                                                        value="other"
                                                        <s:property value="setTag('q' + #qId,'other','checked')" />
                                                        >其他
                                                <s:if test="#q.otherStyle == 1">
                                                    <input type="text" 
                                                            class="text" 
                                                            name='q<s:property value="#qId"/>other'
                                                            <s:property value="setText('q' + #qId + 'other')" />
                                                            >
                                                </s:if>
                                                <!-- 其它选项类型是下拉列表 -->
                                                <s:elseif test="#q.otherStyle == 2">
                                                    <select name='q<s:property value="#qId"/>other'>
                                                        <s:iterator var="option" value="#q.otherSelectOptionArr" status="optst">
                                                            <option value='<s:property value="#optst.index" />'
                                                                    <s:property value="setTag('q' + #qId+'other',#optst.index,'selected')" />
                                                                    ><s:property /></option>
                                                        </s:iterator>
                                                    </select>
                                                </s:elseif>
                                            </s:if>
                                        </s:if>
                                        
                                        <!-- 非矩阵是下拉列表 -->
                                        <s:if test="#qt == 4">
                                            <select name='q<s:property value="#qId" />'>
                                                <s:iterator var="option" value="#q.optionArr" status="optst">
                                                    <option value='<s:property value="#optst.index" />'
                                                            <s:property value="setTag('q' + #qId,#optst.index,'selected')" />
                                                            ><s:property /></option>
                                                </s:iterator>
                                            </select>
                                        </s:if>
                                        
                                        <!-- 非矩阵式文本框 -->
                                        <s:if test="#qt == 5">
                                            <input type="text" 
                                                name='q<s:property value="#qId" />'
                                                <s:property value="setText('q' + #qId)" />
                                                >
                                        </s:if>
                                        
                                        <!-- 如果题型是矩阵式题型 -->
                                        <s:if test='#qt> 5'>
                                            <table>
                                                <!-- 列标题行(表头,表头第一列是空) -->
                                                <tr>
                                                    <td></td>
                                                    <!-- 循环输出列表标题数组 -->
                                                    <s:iterator var="col" value="#q.matrixColTitleArr">
                                                        <td><s:property value="#col" /></td>
                                                    </s:iterator>
                                                </tr>
                                                <!-- 循环输出每一行,对行标题数组进行遍历 -->
                                                <s:iterator var="row" value="#q.matrixRowTitleArr" status="rowst">
                                                    <tr>
                                                        <td><s:property value="#row" /></td>
                                                        <!-- 循环输出控件 -->
                                                        <s:iterator var="col" value="#q.matrixColTitleArr" status="colst">
                                                            <td>
                                                                <!-- 矩阵式单选按钮 -->
                                                                <s:if test="#qt == 6">
                                                                    <input type="radio" 
                                                                            name='q<s:property value="#qId+'_' + #rowst.index" />' 
                                                                            value='<s:property value="#rowst.index + '_' + #colst.index"/>'
                                                                            <s:property value="setTag('q' + #qId+'_' + #rowst.index,#rowst.index + '_' + #colst.index,'checked')" />
                                                                            >
                                                                </s:if>
                                                                <!--  矩阵式复选 -->
                                                                <s:elseif test="#qt == 7">
                                                                    <input type="checkbox" 
                                                                        name='q<s:property value="#qId" />' 
                                                                        value='<s:property value="#rowst.index+'_' +#colst.index"/>'
                                                                        <s:property value="setTag('q' + #qId,#rowst.index + '_' + #colst.index,'checked')" />
                                                                        >
                                                                </s:elseif>
                                                                <!-- 矩阵式下拉列表 -->
                                                                <s:elseif test="#qt == 8">
                                                                    <select name='q<s:property value="#qId"/>'>
                                                                        <s:iterator var="option" value="#q.matrixSelectOptionArr" status="optst">
                                                                            <option value='<s:property value="#rowst.index+'_'+#colst.index+'_'+#optst.index"/>'
                                                                                    <s:property value="setTag('q' + #qId,#rowst.index + '_' + #colst.index+'_' +#optst.index,'selected')" />
                                                                                    ><s:property value="#option"/></option>
                                                                        </s:iterator>
                                                                    </select>
                                                                </s:elseif>
                                                            </td>
                                                        </s:iterator>
                                                    </tr>
                                                </s:iterator>
                                            </table>
                                        </s:if>
                                    </td>
                                </tr>
                            </s:iterator>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" align="center">
                        <!-- 构造上一步按钮 -->
                        <s:if test="currPage.orderno != #session.current_survey.minOrderno">
                            <input type="submit" name='submit_pre' value='<s:property value="#session.current_survey.preText"/>' class="btn">
                        </s:if>
                        <!-- 构造下一步按钮 -->
                        <s:if test="currPage.orderno != #session.current_survey.maxOrderno">
                            <input type="submit" name='submit_next' value='<s:property value="#session.current_survey.nextText"/>' class="btn">
                        </s:if>
                        <!-- 构造完成按钮 -->
                        <s:if test="currPage.orderno == #session.current_survey.maxOrderno">
                            <input type="submit" name="submit_done" value='<s:property value="#session.current_survey.doneText"/>' class="btn">
                        </s:if>
                        <input type="submit" name="submit_exit" value='<s:property value="#session.current_survey.exitText"/>' class="btn">
                    </td>
                </tr>
            </table>
            </s:form>
    </body>
</html>
engageSurvey.jsp

参与调查页面是每页显示的,点击上一页,下一页按钮时会把当前页的参数保存到session中。

    /**
     * 处理参与调查
     */
    public String doEngageSurvey(){
        String submitName = getSubmitName();
        //上一步
        if(submitName.endsWith("pre")){
            mergeParamsIntoSession();
            this.currPage = surveyService.getPrePage(currPid);
            return "engageSurveyPage" ;
        }
        //下一步
        else if(submitName.endsWith("next")){
            mergeParamsIntoSession();
            this.currPage = surveyService.getNextPage(currPid);
            return "engageSurveyPage" ;
        }
        //完成
        else if(submitName.endsWith("done")){
            mergeParamsIntoSession();
            //绑定令牌到当前线程
            SurveyToken token = new SurveyToken();
            token.setCurrentSurvey(getCurrentSurvey());
            SurveyToken.bindingToken(token);
            
            //TODO 答案入库
            surveyService.saveAnswers(processAnswers());
            
            return "engageSurveyAction" ;
        }
        //退出
        else if(submitName.endsWith("exit")){
            clearSessionData();
            return "engageSurveyAction" ;
        }
        return null ;
    }



/**
     * 将参数合并到session中
     */
    private void mergeParamsIntoSession() {
        Map<Integer, Map<String,String[]>> allParamsMap = getAllParamsMapInSession();
        allParamsMap.put(currPid, paramsMap);
    }
    
    /**
     * 获得sesson中所有参数的map
     */
    @SuppressWarnings("unchecked")
    private Map<Integer, Map<String, String[]>> getAllParamsMapInSession() {
        return (Map<Integer, Map<String, String[]>>) sessionMap.get(ALL_PARAMS_MAP);
    }


/**
     * 清除session数据,释放资源
     */
    private void clearSessionData() {
        sessionMap.remove(CURRENT_SURVEY);
        sessionMap.remove(ALL_PARAMS_MAP);
    }
engageSurveyAction.java

页面中的setTag方法,默认选择

/**
     * 设置选中标记
     */
    public String setTag(String name,String value,String tag){
        Integer pid = this.currPage.getId();
        Map<String,String[]> map = this.getAllParamsMapInSession().get(pid);
        String[] oldValues = map.get(name);
        if(StringUtil.contains(oldValues,value)){
            return tag ;
        }
        return "" ;
    }
    
    public String setText(String name){
        Integer pid = this.currPage.getId();
        Map<String,String[]> map = this.getAllParamsMapInSession().get(pid);
        String[] oldValues = map.get(name);
        if(ValidateUtil.isValid(oldValues)){
            return " value='" + oldValues[0] + "'" ;
        }
        return "" ;
    }
    
View Code

处理答案方法

    /**
     * 处理答案
     */
    private List<Answer> processAnswers() {
        //矩阵式单选按钮
        Map<Integer, String> matrixRadioMap = new HashMap<Integer, String>();
        
        List<Answer> answers = new ArrayList<Answer>();
        Answer a = null ;
        String key = null ;
        String[] value = null ;
        for(Map<String,String[]> map : getAllParamsMapInSession().values()){
            for(Entry<String, String[]> entry : map.entrySet()){
                key = entry.getKey();
                value = entry.getValue();
                //挑选所有q开头的参数
                if(key.startsWith("q")){
                    //不含other,也不含"_"
                    if(!key.contains("other") && !key.contains("_")){
                        a = new Answer();
                        a.setAnswerIds(StringUtil.arr2Str(value));//answerids
                        a.setQuestionId(getQid(key));//questionid
                        a.setSurveyId(getCurrentSurvey().getId());//surveyid
                        //处理其他项
                        String[] otherValue = map.get(key+"other");
                        a.setOtherAnswer(StringUtil.arr2Str(otherValue));//otheranswer
                        answers.add(a);
                    }
                    //处理矩阵式单选按钮
                    else if(key.contains("_")){
                        //问题
                        Integer qid = getMatrixRadioQid(key);
                        String oldValue = matrixRadioMap.get(qid);
                        if(oldValue == null){
                            matrixRadioMap.put(qid, StringUtil.arr2Str(value));
                        }
                        else{
                            matrixRadioMap.put(qid, oldValue + "," + StringUtil.arr2Str(value));
                        }
                    }
                }
            }
        }
        //单独处理矩阵式单选按钮
        processMatrixRadioAnswers(answers,matrixRadioMap);
        return answers;
    }
    
    /**
     * 单独处理矩阵式单选按钮
     */
    private void processMatrixRadioAnswers(List<Answer> answers,
            Map<Integer, String> matrixRadioMap) {
        Integer key = null ;
        String value = null ;
        Answer a = null ;
        for(Entry<Integer, String> entry : matrixRadioMap.entrySet()){
            key = entry.getKey();
            value = entry.getValue();
            a = new Answer();
            a.setAnswerIds(value);//answerids
            a.setQuestionId(key);
            a.setSurveyId(getCurrentSurvey().getId());//surveyid
            answers.add(a);
        }
    }
    /**
     * 得到矩阵式单选按钮问题id:q12_0 --> 12 
     */
    private Integer getMatrixRadioQid(String key) {
        return Integer.parseInt(key.substring(1, key.indexOf("_")));
    }
    //取得调查
    private Survey getCurrentSurvey() {
        return (Survey) sessionMap.get(CURRENT_SURVEY);
    }
    //提取问题id:q12-->12
    private Integer getQid(String key) {
        return Integer.parseInt(key.substring(1));
    }
View Code

保存答案的方法

/**
     * 保存答案
     */
    public void saveAnswers(List<Answer> list){
        String uuid = UUID.randomUUID().toString();
        Date date = new Date();
        for(Answer a : list){
            a.setUuid(uuid);
            a.setAnswerTime(date);
            answerDao.saveEntity(a);
        }
    }
View Code

 

与考试系统的设计思路比较类似,这个Struts版本的看的实在不熟悉,程序正常跑起来了,但是很多按钮无法显示,估计是需要配合JDK6和tomcat6, 不想降版本就这样凑合着理解一下设计思路。教学视频有点恶心,关键到这里了文件加密。  复杂点的可以学习一下百度自动表单设计。

posted @ 2017-04-13 11:42  SKYisLimit  阅读(130)  评论(0)    收藏  举报