web项目一些小知识
form表单中所有按钮默认会被当做提交按钮,所以不要在form表单中用多个按钮,可以用按钮外观的a标签来替换除提交按钮之外的其他按钮(bootstrap中只需要加上class="btn"就可以获得按钮外观)。
jquery对象和DOM对象是不同的,使用方法时必须注意区分调用方法的对象是何种类型,比如 $("#p1").html("123");document.getElementById("p1").innerHTML="123";前者是jquery方法,后者是DOM方法。
jquery中使用val(),原生js用value,还有类似比如text()和textContent等。jquery对象是对DOM对象进行包装后的对象。通过使用get(索引值)或者[索引值]的方式可以把jquery对象转换为DOM对象,$()包裹dom对象就能得到jquery对象
比如$("#p1")[0].innerHTML="123"或者$("#p1").get(0).innerHTML="123"都是可行的。
文本框、密码框、文本域输入值获取用textContent或者jquery的val()方法,span标签中的文本值jquery的text()方法。
在实际开发中常常需要选中触发事件的对象本身,比如触发点击事件的按钮等等,可以采用如下方式:
<button value="点击" onclick="test($(this))">
<script>
function test(obj){
console.info(obj);
}
</script>
日期类型如果是年月日格式可以用Date存储,如果是年月日时分秒可以用Timestamp存储,Timestamp默认精确到0.001秒(1毫秒),在如果某个实体的属性是从数据库中取出的Timestamp类型,那么虽然后台看到的是年月日时分秒格式,
但是通过ObjectMapper发送到前台时会变成毫秒数,这时可以通过在传输前设置mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))来解决。
获得下拉列表的选中项可以直接用jquery的val()方法,比如#("#select123").val(),如果value中传递了参数,表示设置默认选中值。
例如有如下下拉列表:
<select id="sel1">
<option value="亚洲" selected>亚洲</option>
<option value="欧洲">欧洲</option>
<option value="非洲">非洲</option>
</select>
$("#sel1").val()得到的结果是:亚洲,因为上面的下拉列表设置默认选中值是亚洲。而如果$("#sel1").val("欧洲")表示让下拉列表中value为"欧洲"的option被选中,这一点常用在修改界面显示用户修改前的旧信息。
通过给输入文本框和文本域设置设置value="XXXX"可以直接设置默认值,而不用通过js代码来设置,配合el表达式使用非常方便,尤其是在修改功能中,比如修改前在请求中设置一个属性,值为要修改的对象。
如果想要通过在请求中设置属性的方式将参数传递给下一个页面,那么必须用请求转发的方式,而决不能用重定向,因为重定向会丢失请求,客户端第一次请求到达服务器,服务器返回一个重定向的地址,客户端再次发送第二次请求,
之前设置的属性已经丢失了。
例如 request.setAttribute(user),然后在需要显示并修改电话输入框可以直接写成 电话:<input value="${user.tel}"/>
select.options可以直接获取到下拉列表的option数组,这是原生js方法。
jsp页面的js中可以直接使用el表达式来获取jsp中的变量值,但仅限于jsp页面,比如session中有个name属性,js代码中可以写为:var name="${name}",注意要加引号!
当然也可以在页面中用隐藏的方式储存我们需要的信息,再利用选择器获取我们想要的内容。例如:session中有userName属性,我们可以将其放在span标签中然后在页面隐藏,js代码中获取对应span标签的文本就可以取得想要的值
<span id="userName" style="display:none">${userName}</span> -----------------js中$("#userName").text()就可以获取到值
当然最常用的做法是隐藏表单<input type="hidden" value="${userName}" name="userName">配合spring MVC使用
与session默认支持存放对象不同,cookie默认存放字符串,如果要存放对象,则需要进行序列化传送和反序列化解析。cookie默认不支持中文,也不支持逗号空格下划线等特殊字符,
假如cookie中属性值为中文,那么需要进行编码和解码。比如:
设置cookie中文属性值:String name="张三";int id=1;Cookie cookie=new Cookie("name_id",URLEncoder.encode(name+","+id,"utf-8"));
获取cookie中文属性值:String name=URLDecoder.decode(cookie.getValue(),"UTF-8"),然后按照拼接时候的特点拆分字符串
当自己编写了一个方法根据传过来的请求获取其中的参数值并自动装配成bean时,如果请求中包含的属性在对应实体类中找不到该属性,那么就会抛出异常,然后获取枚举对象是根据表单中元素的name属性
来获得的,所以只要不给不需要的表单元素设置name属性,就可以避免异常。比如"确认密码"这一input元素就不需要设置name,只给输入密码的input设置name,并且名称和实体类对应属性保持一致就行。
word-wrap:break-word;word-break:break-all;在style中加入这两句话可以解决div内文字超div边界问题,让文字自动换行
js的方法中默认情况下中文参数是无法解析的,除了进行编码和解码外。还可以通过加引号的方式,需要注意的是,在ajax中拼接a标签指向某个js方法时,如果参数是中文,那么就需要将中文参数用引号包起来,这时候会出现三重引号,第三重必须用转义引号。
例如在ajax中,$.post("/user/findById","id=1",function(user){
console.info(JSON.stringify(user))//表示把JSON对象转化为字符串,这里的JSON必须大写
//ajax中获得了后台返回的user对象,包含了属性id和姓名userName(值为中文)
var str="<a href='javascript:showDetail("+user.id+",\""+user.userName+"\"')>查看</a>"
....后续操作
},"jason")
function showDetail(id,name){
alert(id+" "+name)
}
效果如图,发现中文参数"张三"被包在引号中,且控制台中正确打印出中文信息
反之,如果上面没加引号,也没有通URIencoder编码处理,可以看到,虽然鼠标移到a标签上能够显示中文,然后方法中的中文并不能识别并会报错
servlet中文乱码处理
如果是post
设置req.setCharacterEncoding("utf-8");
如果是get,不去修改服务器配置的情况下
new String(name.getBytes("iso-8859-1"),"utf-8")
a标签进行页面跳转时,如果路径中拼接了中文参数,那么即使过滤器中设置了response.setCharacterEncoding("utf-8") 也会出现乱码,因为这种设置针对的是post方式,而a标签是get方式,比如路径
http://localhost:8080/jobProject/index.jsp?name=张三,张三会乱码,如果是jsp页面,可以在脚本中利用java代码进行转换,如,String
name=new String(request.getParameter("iso8859-1"),"utf-8")。
如果不是jsp页面,那么需要编码和解码
数据库乱码
jdbc:mysql://127.0.0.1:3306/dbName?useUnicode=true&characterEncoding=UTF-8
对web项目而言,可以通过自定义一个类实现ServletContextListener接口,并重写public void contextInitialized(ServletContextEvent servletContextEvent) {}和public void contextDestroyed(ServletContextEvent servletContextEvent) {}来实现一些容器启动和销毁时的操作,例如容器启动时初始化一些应用级别的缓存数据,容器销毁时清除缓存。例如,项目中有遇到省市县三级下拉联动,而省的名称和编码是固定的,这时可以在容启动时便将其查询并绑定在ServletContext中,以便后续使用。
jsp页面中可以使用自定义标签:
例如在WEB-INF目录下的tags文件夹中定义如下add.tag:
<%@ tag body-content="empty" trimDirectiveWhitespaces="true" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ attribute name="x" required="true" rtexprvalue="true" %>
<%@ attribute name="y" required="true" rtexprvalue="true" %> <div> <h4>The result of x+y is</h4> result = ${x+y}
</div>
在Index.jsp中引用该标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
tagdir表示自定义标签存放的目录,prefix表示引用自定义标签使用的前缀 <%@ taglib tagdir="/WEB-INF/tags/" prefix="mytag" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>define tag</title> </head> <body> <mytag:add x="1" y="2"/> </body> </html>
示例2,引用下拉列表的自定义标签 selectProvince.tag
<%@ tag pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- required="true"表示该属性是必须的-->
<%@ attribute name="id" required="true"%>
<%@ attribute name="onChange"%>
<%@ attribute name="html"%>
<%@ attribute name="selected"%>
<%@ attribute name="readonly"%>
<c:if test="${not empty id}">
<c:set var="htmlId" value="${id}" />
</c:if>
<c:set var="htmlAttr" value="" />
<c:if test="${not empty onChange}">
<c:set var="htmlAttr" value="onChange='${onChange}'" />
</c:if>
<select id="${htmlId}" <c:if test="${!empty readonly}">readonly="readonly"</c:if> name="${htmlId}" ${htmlAttr} ${html}>
<option value="">请选择</option>
<c:forEach var="province" items="${applicationScope.provinceMap}">
<option value="${province.key}" <c:if test="${selected == province.key}">selected</c:if>>${province.value}</option>
</c:forEach>
</select>
引用时,
<tags:selectProvince id="provinceCode" html="class='form-control input-sm' style='border-width: 1px;'"
selected="${studentInfo.provinceCode}" ></tags:selectProvince>