表单功能无论是在网页设计还是app软件开发领域都得到了大量的使用。
今天贵阳北大青鸟http://www.kmbdqn.cn/就一起来了解一下,符合用户体验的表单设计需要满足哪些条件。
1、表单标签需采用合适的展现形式根据表单的运用场景,标签应采用对应的展现形式,常见的展现形式有以下三种:左标签、顶部标签、行内标签。
A.左标签在一些网页表单当中,标签局左是常见的一种形式。
左标签的展示形式给人一种秩序感,也便于用户在填写表单的过程中快速的辨别标签内容。
左标签的这种形式一般用于网页当中,不适合在手机端或者小屏下的移动端出现,因为小屏幕的尺寸有限,标签居左会占用较大的空间,输入框就会受限。
B.顶部标签顶部标签指的是标签位于输入框上方,这种形式一般出现在一些移动端当中。
顶部标签可以使输入框的宽度变大,用户在填写信息也可以比较得到完整的展示。
但这种布局方式也有一个缺不好的点,就是这个表单可能需要滚屏,用户才可以看完。
C.行内标签行内标签常常出现在手机端的注册界面当中,这样的设计可以节省页面空间,所以大部分app的界面设计都采用这样的设计。
当然,部分网站pc端的表单设计中也会用到这种设计。
2、英文标签避免全部大写一些英文界面的表单设计,我们要避免标签的全大写。
全部大写的标签容易造成阅读和浏览上的困难。
3、特殊标签需使用合适的输入框长度对于特定的标签,像验证码、邮编这样的标签,在设计的时候需要采用合适的输入框长度。
毕竟这样的输入框是用户可预见的,所以输入框的长度可以不需要太长。
4、复选框排列需注意在表单中常出现复选框的设计,这样的情况需要特殊处理。
比如在注册的过程中,会有性别的选择,所以通常设计该表单的时候我们会将男女横排在一行。
但是对于内容多的情况下,就建议采用竖排的排序方式。
5、主按钮和辅按钮需要明确的区分在表单提交的时候,出现多个按钮的情况下,需要做明确的区分,这样有利于用户在操作过程中方便辨别操作步骤。
1.js方法解决:关于js方法解决就是说通过js动态控制提交按钮不能多次点击,或者多次点击不起作用。
方案一:通过设立标识使表单不能重复提交:
var flag=true function Sub(){ if(flag){
flag = false
document.form1.onsubmit()
}
}
方案二:一次点击后使得提交按钮变成不可用
<input type="button" value="login" onclick="this.disabled=truethis.form.submit()" />
总的来说,js解决方案是基本可以防止重复点击提交按钮造成的重复提交问题,但是前进后退操作,或者F5刷新页面等问题并不能得到解决。
最重要的一点,前端的代码只能防止不懂js的用户,如果碰到懂得js的编程人员,那js方法就没用了。
2.设置HTTP报头,控制表单缓存,使得所控制的表单不缓存信息,这样用户就无法通过重复点击按钮去重复提交表单。
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
但是这样做也有局限性,用户在提交页面点击刷新也会造成表单的重复提交。
3.通过PRG设计模式(用来防止F5刷新重复提交表单):
PRG模式通过响应页面Header返回HTTP状态码进行页面跳转替代响应页面跳转过程。具体过程如下:
客户端用POST方法请求服务器端数据变更,服务器对客户端发来的请求进行处理重定向到另一个结果页面上,客户端所有对页面的显示请求都用get方法告知服务器端,这样做,后退再前进或刷新的行为都发出的是get请求,不会对server产生任何数据更改的影响。
但此方法也不能防止所有情况:例如用户多次点击提交按钮恶意用户避开客户端预防多次提交手段,进行重复提交请求
以上都说的是在客户端如何防止表单重复提交,下面说一下服务器端有哪些可行的方法。
4.如果是注册或存入数据库的操作,可以通过在数据库中字段设立唯一标识来解决,这样在进行数据库插入操作时,因为每次插入的数据都相同,数据库会拒绝写入。这样也避免了向数据库中写入垃圾数据的情况,同时也解决了表单重复提交问题。
但是这种方法在业务逻辑上感觉是说不过去的,本来该有的逻辑,缺因为数据库该有的设计隐藏了。而且这种方法也有一定的功能局限性,只适用于某系特定的插入操作。
5.session方法:
在struts框架中防止表单重复提交的方法是生成Token存入session,以此判断表单是否是第一次提交。以下给大家解释一下运行流程。
首先客户端请求服务器中的表单,服务器将客户机所请求的表单发给客户机同时发送一个特殊的随机数(Token)作为表单号存在表单的隐藏域中(type=hidden),并且存入服务器端的session中。
在客户端填写完表单内容向服务器提交时,同时也将隐藏域中的表单号发给服务器端,服务器端此时会检测服务器端的表单号是否存在,如果存在,则进行提交操作,并删除此表单号,否则,服务器视为客户机端重复提交表单,不予操作。
此处贴出生成Token的代码(保证随机数的独一无二性):
class Token{ private Token(){} private static Token instance = new Token()
public Token getinstance(){ return instance
}
//随机数发生器
public String getToken(){
String token = System.currentTimeMillis() + "" + new Random().nextInt()//获得毫秒数加随机数
try {
MessageDigest md = MessageDigest.getInstance("md5") byte[] md5 = md.digest(token.getBytes())
BASE64Encoder base = new BASE64Encoder()
base.encode(md5)
} catch (NoSuchAlgorithmException e) {
e.printStackTrace()
}
return null
}
}
要强调的是,利用session方法解决表单重复问题是十分完美的,基本上可以应对各种重复提交问题。
但!是不是之前在客户端防止表单重复提交的种种方法就不使用了呢?
答案是否定的,我们需要多种方法混合使用才能达到最好的效果,也许有人会问,不是说session方法基本可以应对各种重复提交问题了吗?
这里我们所说的达到最好效果指的是,给用户更好地体验,例如用户点击了提交按钮,这时将按钮变为不可用的,用以告诉用户你已经提交内容了,不可重复提交。还有如果无论什么情况都用session防止表单重复提交问题,反而无形的增加了服务器端的负担。
你的问题本身就有太多疑问,想帮都帮不上。1.什么表?是EXCEL的表吗?如果是,等下告诉你如何POI插件实现.
2.存储到什么记录?数据库?什么数据库?SQL SERVER?如果是,同样等下告诉你方法
3.是纯JAVA实现还是可以JSP实现?因为用JSP实现也挺简单的。
这样吧,我就在一知半解的情况下给出解决办法吧:
1.首先,这个是JSP实现的通过上传EXCEL表然后存储到SQL SERVER中的代码:
(PS:首先要用JXL包)
<%@ page contentType="text/htmlcharset=gb2312"%>
<%@ page import="java.io.*,jxl.*,jxl.write.*,jxl.write.*,jxl.format.*"%>
<%@page import="java.sql.*"%>
<%@page import="java.util.*"%>
<%@ page import="java.awt.*"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="com.jspsmart.SmartFile"%>
<jsp:useBean id="common" class="com.teach.db.commonMethod" scope="page">
</jsp:useBean>
<%//实现EXCEL文件上传,上传之后把EXCEL文件中的内容导入SQL server数据库中
//用smartUpload组件把EXCEL文件上传
com.jspsmart.SmartUpload smartUpload = new com.jspsmart.SmartUpload()//初始化smartUPload
smartUpload.initialize(pageContext)
smartUpload.service(request, response)
smartUpload.upload()
com.jspsmart.SmartFile file = smartUpload.getFiles().getFile(0)//得到上页输入的文件
//取中文表单参数
String newFileName = "test.xls"
//改名上传
file.saveAs("excel/" + newFileName, smartUpload.SAVE_VIRTUAL)
%>
<%!public String codeToString(String str) {//处理中文字符串的函数
String s = str
try {
byte tempB[] = s.getBytes("ISO-8859-1")
s = new String(tempB)
return s
} catch (Exception e) {
return s
}
}
%>
<html>
<head>
<title></title>
</head>
<body>
<%//得到前页传过来的参数
String courseId=session.getAttribute("courseId").toString()
%>
<%String path = request.getRealPath("\\") + "excel" + "\\"
+ "test.xls"//Excel文件URL
InputStream is = new FileInputStream(path)//写入到FileInputStream
jxl.Workbook wb = Workbook.getWorkbook(is)//得到工作薄
jxl.Sheet st = wb.getSheet(0)//得到工作薄中的第一个工作表
int rsRows = st.getRows()//得到excel的总行数
for (int i = 1i <rsRowsi++) {
Cell cell0 = st.getCell(0, i)//得到工作表的第一个单元格,即A1
Cell cell1 = st.getCell(1, i)//得到工作表的第二个单元格,即A1
try {
String content0 = cell0.getContents()//getContents()将Cell中的字符转为字符串
int content1 = Integer.parseInt(cell1.getContents())//得到条形码
//存入数据库
String sql = "insert into sy_score(courseId,scoreStudentName,score)"
+ "values("
+ courseId
+ ",'"
+ content0
+ "',"
+ content1+")"
System.out.println(sql)
common.Del_Insert(sql)//执行SQL语句
} catch (Exception e) {
//如果EXCEL文件中输入的数据有错,则跳过此行数据
session.setAttribute("message", "有错误,不能导入,请检查您的excel文件")
continue
}
}
wb.close()//关闭工作薄
is.close()//关闭输入流
response.sendRedirect("insert_done.jsp")//转到成功页
%>
</body>
</html>
2.如果不是要JSP的,那么来看看用纯JAVA如何实现:
(PS:要用到APACHE的POI)
用Apacher的POI读取Excel,再写入SQL Server就可以
这个是读取的例子 读取分析完后直接写入库中就行
public class ReadExcelToSql
{
private void readExcel(File file)
{
DecimalFormat df = new DecimalFormat("#")
try
{
HSSFWorkbook book=new HSSFWorkbook(new FileInputStream(file))
for(int numSheets=0numSheets<book.getNumberOfSheets()numSheets++)
{
if(null!=book.getSheetAt(numSheets))
{
//System.out.println("Sheet存在")
HSSFSheet sheet=book.getSheetAt(numSheets)
for(int numRows=0numRows<=sheet.getLastRowNum()numRows++)
{
if(null!=sheet.getRow(numRows))
{
//System.out.println("Row存在")
HSSFRow row=sheet.getRow(numRows)
for(short numCells=0numCells<=row.getLastCellNum()numCells++)
{
if(null!=row.getCell(numCells))
{
HSSFCell cell=row.getCell(numCells)
int cellType=cell.getCellType()
switch(cellType)
{
case 0:
System.out.print(df.format(cell.getNumericCellValue()))
break
case 1:
System.out.print(cell.getRichStringCellValue())
break
default:break
}
System.out.print("\t")
}
}
System.out.println()
}
}
}
}
}catch(Exception ex)
{
ex.printStackTrace()
}
}
}
具体表项之间的对应你自己稍微设计一下就可以了。还有不明白的可以给我留言.