调查统计系统——参与调查与答案的保存
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; } }
<%@ 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>
参与调查页面是每页显示的,点击上一页,下一页按钮时会把当前页的参数保存到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); }
页面中的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 "" ; }
处理答案方法
/** * 处理答案 */ 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)); }
保存答案的方法
/** * 保存答案 */ 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); } }
与考试系统的设计思路比较类似,这个Struts版本的看的实在不熟悉,程序正常跑起来了,但是很多按钮无法显示,估计是需要配合JDK6和tomcat6, 不想降版本就这样凑合着理解一下设计思路。教学视频有点恶心,关键到这里了文件加密。 复杂点的可以学习一下百度自动表单设计。

浙公网安备 33010602011771号