这些是过去工作中碰到的问题,以前就用记事本记录了下来,现在统一放在这里作为合集,以后碰到了也将继续放到这里面,以防丢失。
1.中文前台到后台乱码
前台:type = encodeURI(encodeURI(type));
后台:type = URLDecoder.decode(type, "utf-8");
2.生成随机字符串
方式一:
public static String getRandomString(int length) { //length表示生成字符串的长度
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
方式二:
String smsStr = RandomStringUtils.random(6);
3.Struts2从后台传递数据到前台的主要方法和流程 两种主要方式:
一 和Servlet API耦合的访问方式
二 和Servlet API解耦的访问方式
********************************************************************
一 和Servlet API耦合的访问方式
1、 采用Request (HttpServletRequest)对象来传递数据
(1)在Action类文件中
(A) 导入ServletActionContext类:
import org.apache.struts2.ServletActionContext;
(B) 获得request对象,具体的方法如下:
HttpServletRequest request = ServletActionContext.getRequest ();
(C)通过setAttribute()方法把需要传递的数据对象放入request对象中:
request.setAttribute("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) request.getAttribute("key")获得被传递的数据对象。
(B) <s:iterator value="#request.key"> 获得被传递的数据对象。
2、采用application (ServletContext) 对象来传递数据
(1)在Action类文件中
(A) 导入ServletActionContext类:
import org.apache.struts2.ServletActionContext;
(B) 获得application对象,具体的方法如下:
ServletContext application = ServletActionContext.getServletContext ();
(C)通过setAttribute()方法把需要传递的数据对象放入application对象中:
application.setAttribute("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) application.getAttribute("key")获得被传递的数据对象。
(B)<s:iterator value="#application.key"> 获得被传递的数据对象。
3、采用session (HttpSession) 对象来传递数据
(1)在Action类文件中
(A) 导入ServletActionContext类:
import org.apache.struts2.ServletActionContext;
(B) 获得session对象,具体的方法如下:
HttpSession session = ServletActionContext.getRequest ().getSession();
(C) 通过setAttribute()方法把需要传递的数据对象放入session对象中:
session.setAttribute("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) session.getAttribute("key")获得被传递的数据对象。
(B) <s:iterator value="#session.key"> 获得被传递的数据对象。
*********************************************************************************
二和Servlet API解耦的访问方式
1、 采用Request (HttpServletRequest对应的Map对象)对象来传递数据
(1)在Action类文件中
(A) 导入ActionContext类:
import com.opensymphony.xwork2.ActionContext;
(B) 获得request对象,具体的方法如下:
ActionContext context= ActionContext.getContext();
Map request = (Map)context.get("request");
(C)通过put()方法把需要传递的数据对象放入request对象中:
request.put("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) request.getAttribute("key")获得被传递的数据对象。
(B) request.get("key")获得被传递的数据对象。
(C) <s:iterator value="#request.key"> 获得被传递的数据对象。
(D) requestScope.key 获得被传递的数据对象。
2、采用application (ServletContext对应的Map对象) 对象来传递数据
(1)在Action类文件中
(A) 导入ActionContext类:
import com.opensymphony.xwork2.ActionContext;
(B) 获得application对象,具体的方法如下:
ActionContext context= ActionContext.getContext();
Map application = (Map)context.getApplication();
(C)通过put()方法把需要传递的数据对象放入application对象中:
application.put("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) application.getAttribute("key")获得被传递的数据对象。
(B) application.get("key")获得被传递的数据对象。
(C) <s:iterator value="#application.key"> 获得被传递的数据对象。
(D) applicationScope.key 获得被传递的数据对象。
3、采用session (HttpSession对应的Map对象) 对象来传递数据
(1)在Action类文件中
(A) 导入ActionContext类:
import com.opensymphony.xwork2.ActionContext;
(B) 获得session对象,具体的方法如下:
ActionContext context= ActionContext.getContext();
Map session = (Map)context.getSession();
(C)通过put()方法把需要传递的数据对象放入session对象中:
session.put("key",Object);
(2)JSP文件中,有多种方法可以获得被传递的数据对象,比如:
(A) session.getAttribute("key")获得被传递的数据对象。
(B) session.get("key")获得被传递的数据对象。
(C) <s:iterator value="#session.key"> 获得被传递的数据对象。
(D) sessionScope.key 获得被传递的数据对象。
*********************************************************************************
4.表明当前页面可以跨域访问。默认是不允许的。
response.setHeader("Access-Control-Allow-Origin", "*");
5.Base64编码
import org.apache.commons.codec.binary.Base64;
public class testbase_64 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Base64 base64 = new Base64();
String str = "http://192.168.20.100/ssoreserve";
byte[] enbytes = null;
String encodeStr = null;
byte[] debytes = null;
String decodeStr = null;
enbytes = base64.encode(str.getBytes());
encodeStr = new String(enbytes);
debytes = base64.decode(enbytes);
decodeStr = new String(debytes);
System.out.println("编码前:" + str);
System.out.println("编码后:" + encodeStr);
System.out.println("解码后:" + decodeStr);
}
}
6.Base64编码
import org.apache.commons.codec.binary.Base64;
public class testbase_64 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Base64 base64 = new Base64();
String str = "http://192.168.20.100/ssoreserve";
byte[] enbytes = null;
String encodeStr = null;
byte[] debytes = null;
String decodeStr = null;
enbytes = base64.encode(str.getBytes());
encodeStr = new String(enbytes);
debytes = base64.decode(enbytes);
decodeStr = new String(debytes);
System.out.println("编码前:" + str);
System.out.println("编码后:" + encodeStr);
System.out.println("解码后:" + decodeStr);
}
}
7.基于HEX编码转换的AES加密算法
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class JiaMi {
private String iv = "asdj123412341234";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "rich123412341234";
public JiaMi()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ‘ ‘;
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
public static void main(String[] args){
JiaMi jm = new JiaMi();
String str="http://[email protected]#$%/ssoreserve";
System.out.println("加密前:"+str);
String encrypted;
try {
encrypted = JiaMi.bytesToHex(jm.encrypt(str));
System.out.println("加密后:"+encrypted);
String decrypted =new String(jm.decrypt(encrypted));
System.out.println("解密后:"+decrypted);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
8.easyui 日期格式化
function formatterdate(val, row) {
if (val != null) {
var date = new Date(val);
return date.getFullYear() + ‘-‘ + (date.getMonth() + 1) + ‘-‘ + date.getDate();
}
}
9.struts2中<s:if>标签的使用
A:<s:if>判断字符串的问题:
1、判断单个字符:<s:if test="#session.user.username==‘c‘">
这样是从session中取出username的值,并且判断其是否为c,但是这样判断是不正确的,这样判断的话,根本判断不出来,要改成下面这样:
<s:if test="#session.user.username==‘c‘.toString()">
这样判断才能正确判断,至于原因我也不知道,在网上看到struts2中可能它判断的是char类型。
2、判断字符串:<s:if test="#session.user.username==‘milo‘">
这样写的就是判断username是不是milo,是String的判断,这个是不用加toString()的。
3、判断数值:<s:if test="#session.user.username==0">
这样写的就是判断username是不是0,是int的判断。
B:判断为空的问题:
<s:if test="#session.user.username==null">
struts2中的判空似乎只能这么写
判断非空可以这样写:
<s:if test="#session.user.username!=null" >
举例:
<s:set name="name" value="model.userId" />
<s:if test="#name == ‘luozhh‘">
Luozhh‘s file here
</s:if>
<s:elseif test="#name == ‘Scott‘">
Scott‘s file here
</s:elseif>
<s:else>
Other‘s file here
</s:else>
10.大小写转换:
public static String shift(String str) {
int size = str.length();
char[] chs = str.toCharArray();
for (int i = 0; i < size; i++) {
if (chs[i] <= ‘Z‘ && chs[i] >= ‘A‘) {
chs[i] = (char) (chs[i] + 32);
} else if (chs[i] <= ‘z‘ && chs[i] >= ‘a‘) {
chs[i] = (char) (chs[i] - 32);
}
}
return new String(chs);
}
11.post 请求
public static String post(Map<String, String> params, Map<String, File> files)
throws IOException {
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
String url = GetURL(params);
URL uri = new URL(url);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setReadTimeout(10 * 1000); // 缓存的最长时间
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false); // 不允许使用缓存
conn.setRequestMethod("POST");
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
// 首先组拼文本类型的参数
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINEND);
sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
sb.append(LINEND);
sb.append(entry.getValue());
sb.append(LINEND);
}
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.write(sb.toString().getBytes());
// 发送文件数据
if (files.get("image")!=null){
for (Map.Entry<String, File> file : files.entrySet()) {
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append("Content-Disposition: form-data; name=\"image\"; filename=\""
+ file.getValue().getName().substring(file.getValue().getName().lastIndexOf("/") + 1) + "\"" + LINEND);
sb1.append("Content-Type: image/jpeg; charset=" + CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes());
FileInputStream is = new FileInputStream(file.getValue());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
is.close();
outStream.flush();
outStream.write(LINEND.getBytes());
}
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
// 得到响应码
int res = conn.getResponseCode();
InputStream in = conn.getInputStream();
StringBuilder sb2 = new StringBuilder();
if (res == 200) {
int ch;
while ((ch = in.read()) != -1) {
sb2.append((char) ch);
}
}
outStream.close();
conn.disconnect();
String mResult = sb2.toString();
String result = mResult.substring(3);
return result;
}
12.图片上传
Map<String, String> hashParams = new HashMap<String, String>();
Map<String, File> hashFiles = new HashMap<String, File>();
if (sort.equals("0")) {
hashParams.put(PostApiImp.PARAM_METHOD, PostApiImp.SERVICE_INTERFACE_METHOD_POSTCREATE);
hashParams.put(PostApiImp.PARAM_FORUMID, params[0]);
}else if (sort.equals("1")) {
hashParams.put(PostApiImp.PARAM_METHOD, PostApiImp.SERVICE_INTERFACE_METHOD_POSTREPLY);
hashParams.put(PostApiImp.PARAM_POSTID, params[0]);
}
hashParams.put(PostApiImp.PARAM_UID, appPreference.getString(getString(R.string.UID), null));
String email = appPreference.getString(getString(R.string.LAST_LOGIN_USER),null);
String password =appPreference.getString(getString(R.string.PASSWORD), null);
String token = MD5Util.md5(password+email);
hashParams.put(PostApiImp.PARAM_TOKEN, token);
hashParams.put(PostApiImp.PARAM_TITLE, ett_title.getText().toString());
hashParams.put(PostApiImp.PARAM_CONTENT, ett_content.getText().toString());
hashFiles.put(PostApiImp.PARAM_IMAGE, hashFile);
try {
String temp = UploadPic.post(hashParams, hashFiles);
}catch(Exception e){
//TODO 输出log
}
13.HTTP消息头
HTTP请求中的常用消息头
accept:浏览器通过这个头告诉服务器,它所支持的数据类型
Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集
Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式
Accept-Language:浏览器通过这个头告诉服务器,它的语言环境
Host:浏览器通过这个头告诉服务器,想访问哪台主机
If-Modified-Since: 浏览器通过这个头告诉服务器,缓存数据的时间
Referer:浏览器通过这个头告诉服务器,客户机是哪个页面来的 防盗链
Connection:浏览器通过这个头告诉服务器,请求完后是断开链接还是何持链接
HTTP响应中的常用响应头(消息头)
Location: 服务器通过这个头,来告诉浏览器跳到哪里
Server:服务器通过这个头,告诉浏览器服务器的型号
Content-Encoding:服务器通过这个头,告诉浏览器,数据的压缩格式
Content-Length: 服务器通过这个头,告诉浏览器回送数据的长度
Content-Language: 服务器通过这个头,告诉浏览器语言环境
Content-Type:服务器通过这个头,告诉浏览器回送数据的类型
Refresh:服务器通过这个头,告诉浏览器定时刷新
Content-Disposition: 服务器通过这个头,告诉浏览器以下载方式打数据
Transfer-Encoding:服务器通过这个头,告诉浏览器数据是以分块方式回送的
Expires: -1 控制浏览器不要缓存
Cache-Control: no-cache
Pragma: no-cache
14.计算距离的工具类
public class DistanceUtils {
private static final double EARTH_RADIUS = 6378.137;//地球半径
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 计算经纬度距离,返回单位为公里
* @param lat1 纬度1
* @param lon1 精度1
* @param lat2 纬度2
* @param lon2 经度2
* @return 距离(单位:公里)
*/
public static double getDistance(double lat1, double lon1, double lat2, double lon2) {
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lon1) - rad(lon2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.round(s * 10000) / 10000;
return s;
}
}