这里记录一些小技巧和注意事项:
一、
注册时给密码加密,md5方式,并加“盐”,以确保不会被数据库人员识别密码,也不会被md5库被破解密码。
加密如下:
/**
* Md5加密
*/
public static String md5(String str,String salt){
return new Md5Hash(str,salt).toString();
}
第一个参数就是原密码,salt是干扰参数,计算结果是一串md5密码,此密码不可被反向逆推,所以能保证安全。
在保存时对原密码进行md5计算得到新密码然后保存即可。
使用如下:
/**
* 用户登录
*/
@RequestMapping("/login")
public String login(Users user, HttpServletRequest request){
Subject subject= SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(), CryptographyUtil.md5(user.getPassword(),"gcc"));
try{
subject.login(token);
return "redirect:/index.html";
}catch(Exception e){
e.printStackTrace();
request.setAttribute("user", user);
request.setAttribute("errorMsg", "用户名或密码错误!");
return "redirect:/frontLogin.html";
}
}
在用shiro时将表单密码进行相同方式的md5计算得到对应密码,然后正常使用shiro即可。
二、
在使用mybatis时返回方式由resultMap和resultType两种,笔者原先使用前者,后来习惯使用后者,原因是可以少写点代码,但使用resultType方式返回的数据库字段如果和实体属性名字不相同时,那么得到的数据无法填充到对应字段,这样就出现了一个有趣的bug例如:
查询指定用户名的所有信息,数据库字段如下:
实体字段如下:
然后sql查询后所得实体,除了picUrl字段没有数据,其他都正常,日志也不会报错。
这种情况修改sql(加别名)如下即可:
a.id AS "id",
a.username AS "username",
a.nickname AS "nickname",
a.password AS "password",
a.company AS "company",
a.job AS "job",
a.city AS "city",
a.profile AS "profile",
a.pic_url AS "picUrl"
三、
在开发中,大部分人喜欢使用new Date()来获取时间,使用方便,同时能获取其他信息,比如:小时,分钟等。但只是为了获取毫秒数,就可以直接使用System.currentTimeMillis()来获取,来取代new Date().getTime(),特别是在多次这样调用时,效率上会高一点。
下面是源码:
/**
* Allocates a Date
object and initializes it so that
* it represents the time at which it was allocated, measured to the
* nearest millisecond.
*
* @see java.lang.System#currentTimeMillis()
*/
public Date() {
this(System.currentTimeMillis());
}
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this Date object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
public long getTime() {
return getTimeImpl();
}
private final long getTimeImpl() {
if (cdate != null && !cdate.isNormalized()) {
normalize();
}
return fastTime;
}
四、$.post和$.ajax
笔者原先使用$.ajax,近来觉得$.post书写更顺畅,后者的格式如下:
jQuery.post( url, [data], [callback], [type] ) :使用POST方式来进行异步请求
具体例子如下:
$.post("${pageContext.request.contextPath}/saveArticle.html",
{ 'title':title,
'typeId':typeId,
'content':content
},
function(result){
if(result.flag){
alert("发布成功");
}
},"json");
使用的感觉像是给一个方法传递四个参数,熟悉参数类型即可,而$.ajax简单的实际案例如下:
$.ajax({
type:'get',
url:'http://www.www.daimajiayuan.com/rss',
beforeSend:function(XMLHttpRequest){
//ShowLoading();
},
success:function(data,textStatus){
$('.ajax.ajaxResult').html('');
$('item',data).each(function(i,domEle){
$('.ajax.ajaxResult').append(''+$(domEle).children('title').text()+' ');
});
},
complete:function(XMLHttpRequest,textStatus){
//HideLoading();
},
error:function(){
//请求出错处理
}
});
使用上更加繁琐,而且理解上也有不顺畅的感觉,所以如果您使用的是较为简单的异步响应可以尝试书写更流畅的$.post方式。
注:
$.post的data数据的别名如果和后台接收的对象的属性同名,则会自动赋值给对象实体。
如果使用同步请使用$.ajax; $post默认异步,改同步需要做如下处理:
$.ajaxSettings.async = false;
$.post("/saveArticle.html", data, function(result) {
// 请求处理
},"json");
$.ajaxSettings.async = true;
五、mybatis传参为多种不同类型时怎么处理
给接口方法取别名,使用如下:
List getList(@Param("username") String username, @Param("pageStart") int pageStart, @Param("pageSize") int pageSize);
六,json使用
@ResponseBody
@RequestMapping(value = { "/autoKpiData" })
public String autoKpiData(Master master, HttpServletRequest request) {
try {
String planId = request.getParameter("planId");
String flag=kpiDataService.autoKpiData(master,planId);
String json = JsonMapper.toJsonString(master);
Master master = (Master) JsonMapper.fromJsonString(json,Master.class);
return flag;
} catch (Exception e) {
return e.getMessage();
}
}
1,使用@ResponseBody,返回的数据不是html标签的页面,而是其他某种格式的数据(如json、xml等),可以简化原始的写法,如PrintWriter的处理,如下:
JSONObject result = new JSONObject();
result.put("flag", true);
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println(result.toString());
out.flush();
out.close();
2,通过JsonMapper.toJsonString()将实体类型转换成json类型,可以通过ajax的回调对象result,对象.属性名来取值。
在页面取到规则的(对应属性名字)json值时也可以通过JsonMapper.fromJsonString来将json数据填充到实体属性里。
mavne引入如下:
com.fasterxml.jackson.core
jackson-core
${jackson.version}
com.fasterxml.jackson.core
jackson-databind
${jackson.version}
com.fasterxml.jackson.core
jackson-annotations
${jackson.version}
com.fasterxml.jackson.module
jackson-module-jaxb-annotations
${jackson.version}
对ObjectMapper简单封装的类如下:
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* 简单封装Jackson,实现JSON String<->Java Object的Mapper.
* 封装不同的输出风格, 使用不同的builder函数创建实例.
*/
public class JsonMapper extends ObjectMapper {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
private static JsonMapper mapper;
public JsonMapper() {
this(Include.NON_EMPTY);
}
public JsonMapper(Include include) {
// 设置输出时包含属性的风格
if (include != null) {
this.setSerializationInclusion(include);
}
// 允许单引号、允许不带引号的字段名称
this.enableSimple();
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 空值处理为空串
this.getSerializerProvider().setNullValueSerializer(new JsonSerializer
3,data传值方式如下时:
$.post(
"${ctx}/pa/in/kpiData/autoKpiData",
{
'id':masterId,
'planId':planId,
'groupId':groupId
},
function (result) {
if("Success"==result){
$("#btnSubmit").click();
window.setTimeout(function () { $.jBox.tip('操作成功!', 'success'); }, 500)
}else{
window.setTimeout(function () { $.jBox.tip('操作失败,请确认是否已有考核计划在运行!', 'error'); }, 1000)
}
},
"json"
)
spring也可以将属性名对应的数据填充到实体内:
public String autoKpiData(Master master, HttpServletResponse response,HttpServletRequest request){...}