前言
笔者最近遇到的项目,后端是用 Java Servlet + Jsp + Mysql 实现的,后端中使用的图片托管在七牛云CDN,整个 Java Web 应用是托管在新浪云上的。这儿坐下项目记录,便于自己和其他开发者查阅,如有问题欢迎留言。
新浪云注册
新浪云的好处就是便宜,注册送几千豆,差不多能用几个月,对于初创者是个很好的选择。
新浪云的邀请注册链接 http://t.cn/R4Hwcv6 。根据新浪云的规定,通过邀请注册,邀请人和被邀请人都能获得200豆的奖励。
可以在新浪云上面利用PHP、Python、Java 来开发 Web 程序。
奖励来源 | 双方各获得奖励 | 说明 |
---|---|---|
好友注册成功 | 200云豆 | 需通过邀请链接完成注册 |
好友首次充值>=100元 | 600云豆 | |
好友首次创建独享型MySQL | 200云豆 |
七牛云注册
七牛有 5G 的免费空间,可以存放图片等静态资源,给自己网站、APP提供CDN加速。
通过我的邀请注册七牛 https://portal.qiniu.com/signup?code=3lpzf1unpyr0y 会有优惠奖励。
新浪云的使用技巧
查看应用的日志,有 Http、JVM、数据库日志等等
打印出异常栈轨迹
一般异常都是e.printStackTrace();
这样本地调试的时候可以输出到控制台。但是对于 Web 应用的 Servlet 如何办呢?
笔者是把栈轨迹转换为 String,然后输出到浏览器页面。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
try {
......
} catch (Exception e) {
//将异常栈轨迹转化为字符串
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
//利用 Servlet 的PrintWriter输出到网页
out.print(errors.toString());
}
- 使用 Apache的开源项目Log4j,它是一个功能强大的日志组件。
如何连接新浪云 Mysql
一个问题? 是否能够本地连接新浪云的 Mysql,答案是很难。
新浪云 MySQL 是不支持外部IP直连,有一些中转的方法,但是不太稳定,有需求的小伙伴们可以选择试试。
那么笔者开发的时候,是本地建一个 Mysql,本地测试连接本地的 Mysql。上传到新浪云的时候把地址、用户名、密码修改成新浪云的。
public class MysqlTool {
private static Connection con = null;
// 是否使用新浪云
private static boolean isCloud = true;
// 为了方便分析错误,将异常全部抛出到最顶层
public static Connection getConnection() throws Exception {
if (con != null) {
return con;
}
// JDBC驱动程序
Class.forName("com.mysql.jdbc.Driver").newInstance();
// 后面unicode和utf8设置防止中文乱码
String url = "jdbc:mysql://127.0.0.1:3306/**database_name**?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf-8";
String name = "root";
String password = "**password**";
if (isCloud) {
String appName = SaeUserInfo.getAppName();
String mysqlName = "app_" + appName;
url = "jdbc:mysql://w.rdc.sae.sina.com.cn:3307/" + mysqlName + "?autoReconnect=true";
name = SaeUserInfo.getAccessKey();
password = SaeUserInfo.getSecretKey();
}
con = DriverManager.getConnection(url, name, password);
return con;
}
}
注意上面的代码
name = SaeUserInfo.getAccessKey();
password = SaeUserInfo.getSecretKey();
在本地执行得到的 name 和 password 和云端执行得到的结果是不一样的。
上传到云端后,代码动态获取数据库的用户名和密码,就可以连接数据库了。
Note
新浪云默认的 Mysql 端口是3307,而本地的默认是3306,请大家注意。
中文乱码插入 Mysql
试试在 Url 后面加上useUnicode=true&characterEncoding=utf-8
String url = "jdbc:mysql://127.0.0.1:3306/**database_name**?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf-8";
新浪云预定义的环境变量
说明:使用时需要先导入 SaeUserInfo这个类,使用方式:import com.sina.sae.util.SaeUserInfo
说明 | 使用方法 |
---|---|
Access Key | SaeUserInfo.getAccessKey() |
Secret Key | SaeUserInfo.getSecretKey() |
SAE二级域名前缀 | SaeUserInfo.getAppName() |
应用版本 | SaeUserInfo.getAppVersion() |
SAE临时目录路径 | SaeUserInfo.getSaeTmpPath() |
Mysql 连接的一个bug: Unknown system variable ‘language’
笔者本地连接数据库,增删改查都测试成功了,但是上传到新浪云后却连接数据库不成功。
报的异常信息如下:
java.sql.SQLException: Unknown system variable 'language'
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
mysql-connector-java是mysql的官方驱动,它是java通过JDBC连接操作mysql的驱动。
后来搜索发现,本地的 Mysql 版本是 5.1.。依赖的 Jar 包是 mysql-connector-java-5.1.38.jar
,而新浪云的 mysql 版本是5.0.,连接报上面的错误。
解决方法:换 jar 包,笔者把 jar 包换成了 mysql-connector-java-5.0.8-bin.jar
bug地址 http://bugs.mysql.com/bug.php?id=77665
新浪云集成七牛的一个坑
笔者在本地尝试七牛上传图片是成功的,但是部署到新浪云后上传七牛却不成功。查看异常栈轨迹信息是:
java.lang.UnsupportedClassVersionError: com/squareup/okhttp/RequestBody : Unsupported major.minor version 51.0 yq31.javaruntime
在查看版本 51.0 是对应的 Java7。才发现,笔者本地是 Java 7,七牛也是 Java 7,但是笔者新浪云的应用是 Java 6。
解决方法就是把新浪云的应用改成 Java 7,但是笔者没有找到修改 Java 版本的地方,所以就新建了一个Java 7的应用。
//stanford parser和jdk版本对应关系
J2SE 8 = 52,
J2SE 7 = 51,
J2SE 6.0 = 50,
J2SE 5.0 = 49,
JDK 1.4 = 48,
JDK 1.3 = 47,
JDK 1.2 = 46,
JDK 1.1 = 45