hibernate的文档也会偷懒:Access to DialectResolutionInfo cannot be null when ‘hibernate.dialect’ not set

配置hibernate4的SessionFactory,按照文档配置完毕,总是下面的报错,无法创建factory:

Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

将hbm.cfg.xml中的dialect改成了hibernate.dialect还是不行,嘿,怎么肥事…还解决不了了么。

然后一阵谷歌,发现原来是hibernate的文档没有更新…下面是SessionFactory的生成方法:

Configuration configuration = new Configuration().configure("hbm.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
        .applySettings(configuration.getProperties()).build(); // 就是少了applySettings
SessionFactory factory = configuration.buildSessionFactory(serviceRegistry);

估计新版本需要要将配置应用到serviceRegistry上才行吧,然后文档就这么埋了坑。

通过Java连接mysql对反斜杠“\”转义的测试

在java中,反斜杠“\”转义是“\”,因此表示一个“\”要使用“\\”,如果是正则表达式,那么表示一个“\”需要用“\\\\”,在mysql中,反斜杠转义依然是“\”,和java相同。

现在问题是:如果mysql中一个字段的内容包含反斜杠,然后通过java连接mysql去筛选这个字段所在的条目,要怎么写才能将该字段筛选出来呢?下面就是一个实验:

1,先建立测试数据:

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
insert into test (name) values ('\\'), ('\\\\');

向数据库中插入2条数据,name的值分别是“\”和“\\”。

2,使用jdbc连接mysql,然后测试筛选条件:

Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
PreparedStatement pstmt = conn.prepareStatement("select * from test where *条件"); // “*条件”见下文
pstmt.setString(1, "*筛选值"); // “*筛选值”见下文
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
	System.out.println(rs.getString("name"));
}

继续阅读

Spring自动扫描无法扫描jar包中的bean的解决办法

前几天用eclipse打包了一个jar包,jar包里面是定义的Spring的bean。

然后将jar包放到lib下,设置spring的自动扫描这个jar包中的bean,可谁知根本无法扫描到bean,显示错误就是找不到bean,当时就纳闷儿了,为什么扫描不到,结果搜索之后才发现,用eclipse打包jar包要勾选“Add directory entries”才能被Spring正确扫描到,居然有这个说法,呵呵… 不知道

勾选“Add directory entries”才能被spring扫描到

勾选“Add directory entries”才能被spring扫描到

继续阅读

cas client3.4.x部署包1.0.0发布

cas client部署包也搞定了,因为弄cas server的时候要cas client配合,所以cas client也就一起弄了,文档比cas server少多了,今天一天就搞定了,下面是部署包的连接:

cas-client-3.4.x-deployment-package:
https://github.com/Strangeen/cas-client-3.4.x-deployment-package

介绍还是引用我写的文档的概述吧:

cas client用于部署在应用中,与cas server交互实现单点登录功能,每个需要实现单点登录的应用均需要部署cas client。出于达到对后期快速开发的目的,我在研究cas server的同时,也基于cas官方提供的client模板JA-SIG Java Client Simple WebApp Sample对cas client进行配置和封装出一套部署包,该套部署包需要与cas server部署包同时使用

继续阅读

cas server4.2.x部署包1.0.0发布

抽空时间研究了1个月吧,终于把cas4.2.7搞通了。

配置真的太多太杂了,而且各种文档版本迭代太多,让人搞不清楚到底要怎么配置,还是要拿出杀手锏,有些地方不明白直接干源码… 最终还是搞定了基本的需求配置。

于是,配置了一套部署包,用于后期快速使用和部署,详见我的github:

cas-server-4.2.x-deployment-package:
https://github.com/Strangeen/cas-server-4.2.x-deployment-package

其他的不想写了,文档就断断续续写了1周,写得太累了,介绍就直接引用我写的文档中的概述吧:

cas是yale大学的单点登录系统开源项目,在行业中非常流行,功能也非常强大,但由于cas系统非常庞大,系统和文档版本迭代又比较多,造成各种文档和网上的教程都无法完全匹配,初次使用时的学习成本会非常大。所以出于方便后期快速使用的考虑,我对cas4.2.7进行了学习研究,在我能理解的范围内,将工作和学习中接触过的场景纳入cas进行配置,基于方便统一配置的理念,基于cas4.2.7修改了一些配置文件、文件存放路径以及添加了部分功能,并最终打包封装成了一套仅需极简配置就可以部署完成的系统部署包

Maven构建SpringMVC环境报错“java.lang.ClassNotFoundException: org.springframework.web.servlet. DispatcherServlet”

今天朋友发了个maven项目给我看,问我为什么启动不了。说实话,一直用Jfinal都快不会用spring了… 还是决定看看。

接收了文件,是maven构建的,打开eclipse,导入maven项目,然后部署到tomcat,启动tomcat,就报错了:“java.lang.ClassNotFoundException: org.springframework.web. servlet.DispatcherServlet”,错误信息如下图:

java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

很明显的第一反应就是没有SpringMVC的包,于是检查pom.xml,发现没有问题,spring web mvc包是正确引入了的,查看Maven Dependencies,发现也是正常的,打开jar包,也没有问题,web.xml配置也没有问题…

我去,难道jar包版本问题,于是部署了更高版本的jar包,并且还试过配置更高的JDK版本,依然报错,不能启动…

于是google,发现大部分人都是说没有导入jar包,没有部署成功,可是jar包我导入了,也配置正确了。

就在这时,突然看到有个人说tomcat是否部署成功,于是立刻查看网站部署的文件夹,发现WEB-INF下根本没有lib文件夹… 继续阅读

Filter和HttpServletRequest代理类实现Request参数值更改

前几日写代码,发现没有过滤搜索框输入的特殊字符,比如输入“_”会导致所有数据都被搜索出来(数据库为MySQL),这显然是不正确的,所以决定将搜索关键词中的“_”替换成”\_”,但是我突然想到个问题,这个搜索值获取是在每个Controller中获取的,我必须要找到所有的Controller中获取该参数的代码位置,然后进行修改,然而我并不想这么做…

我想到将request中该参数的值在被Controller获取前更改,然后就不用修改之前的代码就可以实现,但是后面我发现ServletRequest并没有提供修改参数值的方法… 后面经过思考,想到可以制造一个ServletRequest代理类,在代理类中将getParameter重写,即返回需要的值,再将代理类的实例传给Controller使用,这个方法最后验证是可行的。

下面将记录代码,这里使用到Filter,作为请求到达Controller前的拦截器,对request进行代理:

继续阅读

Junit测试中多线程的坑

昨晚用Junit测试多线程,代码如下:

private int i = 3;

@Test
public void test() {
	
	for (int i = 0; i < this.i; i ++) {
		new Thread(new Runner()).start();
	}
}

class Runner implements Runnable {
	
	@Override
	public void run() {
		System.out.printlun(123);
	}
}

发现运行后居然没有任何输出…我又运行了好几次,有时又有1~2句输出,但是始终不全…

当时还以为程序有错,clean了class继续,还是一样的,今天早上起来查了下百度,才明白,原来Junit只管自己的运行,就是说当Junit执行完毕后,就会关闭程序,不会关心是否还有自己启动的后台线程在运行。当Junit运行完毕后,如果后台线程还没有执行完毕,那么也是不会再执行了,所以就出现了昨天的情况…

继续阅读

说个Java三目运算坑

前几日,写代码,用到三目运算,判断一个double,如果大于1则返回int,小于1则返回double,可是依照下面的代码,本应该返回int,即1,但是返回的始终是1.0。

Double d = 1.01;
System.out.println(d > 1 ? d.intValue() : d); // 1.0

当时还在想 d.intValue()返回难道不是 int吗,于是试了下面的代码,结果的确返回的int,即1。

Integer i = d.intValue();
System.out.println(i); // 1

想了好久,突然想到,三目运算的数据类型是相同的,也就是说后面返回的结果和第一个数的类型是一致的!!!第一个数是double,所以返回的结果也会是double,即1.0。

是我自己忘记了…

记一场与java.lang.illegalstateexception: stream的遭遇战

我就像只辛勤的小蜜蜂,每天任劳任怨的撸着码…

今天写服务端向浏览器发送文件的代码,运行后,后台报错java.lang.illegalstateexception: stream,查了资料,找了很久,都没能解决问题…

最后突然发现,这个报错信息上面还有一段…(这什么眼神儿啊,居然没看到上面的报错信息),结果错误不是出在流上面,而是传送数据下面的一句代码,就这句代码造成了illegalstatexception的问题… 我也是醉了。

另外,Jfianl传送完流之后,要使用renderNull(),否则,会报java.lang.illegalstateexception: commited的错误。

来说说那句错误的代码,java中字符串是用双引号,而Oracle中字符串是用单引号,正好单引号又是java中的char字符的表示方式。而我在写在写java时写成了:

Record r = new Record();
r.set("status",'0');

而要设置的这个status字段是CHAR(1 BYTE)类型的,就这样,报错为“不是有效的列类型”… 这就是个坑啊!

Java修道之路:JFinal一坑,事务不回滚问题

其实就是被坑了一下,哪个猿不是从坑里爬出来的呢?有个朋友说过,“有什么坑的,就记下来,下次不要被坑了”,可是,我觉得真是“一朝若被坑,永生真●难忘”,根本不用记录,呵呵。

但,这篇文章不是想描述我如何被坑的,而是为了记录一个处理问题的过程!

使用公司自己的一个eclipse插件做开发,该插件集成了JFinal框架,也不知道是哪个版本的JFinal,不过可以肯定的是2.0以前的。

写了一段业务,删除A表指定记录 -> 插入A表一条记录 -> 批量插入B表n条记录 -> 批量插入C表n条记录(记录从D表中查出),下面是伪代码:

Db.tx(new IAtom() {

	@Override
	public boolean run() throws SQLException {

		try {
			Db.update("delete from A where id = ?", id);
			Db.update("insert into A values(null,?,?)", new Object[]{param1, param2});

			// 准备参数
			Object[][] objss1 = new Object[row][3];
			for (int i = 0; i < row; i ++) {
				objss[i][0] = param3;
				objss[i][1] = param4;
				objss[i][2] = param5;
			}
			Db.batch("insert into B values(null,?,?,?)", objss1, 1000);

			// 准备参数
			Object[][] objss2 = new Object[row][1];
			for (int i = 0; i < row; i ++) {
				objss[i][0] = param6;
			}
			Db.update("insert into C select * from D where id = ?", objss2);

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
});

继续阅读

Java修道之路:Java实现排名

前一篇文章《Java修道之路:MySQL排名》写了如何用SQL来实现排名,这里想用java写一下排名算法,其实主要是想了解下两种方法的耗时,因为之前有同事说SQL的耗时会比Java少,所以想测试一下。

这里先说结果,我写的方法,测出来的结果,Java会比SQL快,也许是我的SQL写得并不优导致的,但是SQL一旦成形,就可以直接套用,使用比较方便,速度呢,1万条数据耗时相差无几,10万条数据(2个字段)耗时相差也就600毫秒左右。

继续阅读

Java修道之路:写一个小小的BUG修复

终于进入项目了,算是慢慢的按照计划步入正轨了吧….开森的同时,问题也接踵而至,这周连续4天加班到快12点了才回去,而我知道这仅仅只是个开始…

刚接到的项目时,觉得应该挺简单,但是花了两周的时间做出来的——却是一坨屎!!!完全不是自己想象的那样,过程也是极其坎坷的。有时候在想,是不是自己又错了!可是回想起决定转行时,这样的情况也是早有觉悟的了,所以,感叹归感叹,路还是要继续的…

感慨完了,说说这个BUG吧。

程序是这样的,后台用JFinal搭建,业务层处理完逻辑后,返回一个Map<String,Object>给控制层,控制层通过renderJson方法返回json数据到浏览器。

Map里的数据是从数据库获取的,当时有个数据作为Map的key值,字符串打印出来看起来是:123456,可是返回到浏览器,用js获取到该key值后,用console.log打印到控制台,却变成了这个样子:”123456 ”

就是说多出了一对引号,导致js无法通过后台传过来的这个key获取到对应的value…当时就懵逼了,其他的key值都没有问题,就这个key值有问题…后来仔细观察,发现123456除了多出一对引号外,数字末尾还多了一个空格!!!一个空格!!!空格!!!格!!!

我去,怪不得会多出一对引号,因为不用引号无法表示这个空格是不是属于这个字符串的…当时发现这个问题时,只有两个字出现在脑海中久久不能散去——坑爹!

话说存数据的时候没有trim的吗?唉,不过既然问题找到了,那么就自己将取出的数据trim一次,然后再renderJson吧,于是问题解决了…庆幸自己是个仔细的人,没有被坑太久。

PS:刚开始写这篇文章的时候,脑子里一直在想一句话,就是“路漫漫其修远兮,吾将上下而求索”,不正是说的我吗!

Java修道之路:JFinal实现自动扫描Controller并设置注解的controllerkey

由于最近在研究JFinal,所以就用JFinal的框框来写例子吧。

JFinal设置Controller的访问路径是在Config的configRoute方法中设置,使用me.add(String path, Class controller),如果有多个Controller,那么需要添加多行代码!

如果Controller非常多,那么后期的更改操作将比较麻烦,所以需要自动扫描Controller,将指定的注解的属性配置到me.add方法中(这里设计为Controller添加自定义注解@PVAnnotation(path = “/visit”),path就是访问路径)。

思路:

1,根据设置的包路径获取到文件路径,使用递归得到所有的.class文件(java字节码文件),将所有的.class的Class放入一个List

2,遍历1中得到的List,通过反射判断Class有没有指定的注解,如果有就获得注解并获得对应的注解属性,如果没有就continue

继续阅读

Java修道之路:jxl操作excel的Demo和详细注释

其实也不是工作中用到了,只是有朋友在问怎么用,也觉得以后多半会用到,所有周末有时间就学学。既然学了又不用,那肯定会忘得比火箭飞得还快……记下来就是最保险的了,将就练习写的几个Demo贴出来,当作技术储备吧,虽说是Demo,但是注释超详细,至少我是这么认为的。

Demo有4个,代码比较长,分段贴出,但是所有代码是在一个类里面的。

下面是引入的包和JUnit的@Before注解

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.junit.Before;
import org.junit.Test;

import jxl.Cell;
import jxl.CellType;
import jxl.DateCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.CellFormat;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.read.biff.BiffException;
import jxl.write.DateFormat;
import jxl.write.DateTime;
import jxl.write.Formula;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFeatures;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class ExcelOperTest {

	private String xlsPath;

	@Before
	public void init() {
		xlsPath = "D:/test.xls";
	}

继续阅读

setContentType(“text/html;charset=utf8”)后页面依然乱码

写了段servlet返回浏览器中文的代码,设置了返回编码为“utf-8”,但是在浏览器端看到的仍是乱码,代码如下:

public class ServletTest extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		PrintWriter pw = res.getWriter();
		res.setContentType("text/html;charset=utf8");
		pw.write("尼美的");
		pw.close();
	}
}

后来发现,setContentType应该写在getWriter前面,所以啊,顺序还是很重要的!!!

res要先设定,才能保证通过res获得的流是utf8的格式。正确代码如下:

public class ServletTest extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		res.setContentType("text/html;charset=utf8");
		PrintWriter pw = res.getWriter();
		pw.write("尼美的");
		pw.close();
	}
}
  • 页数 1 / 3
  • 1
  • 2
  • 3
  • >