瞎忙,或者是邋遢了
到这个月底,在这个单位5年,成了开发人员最老的员工
俺家姑娘下个月两岁了
老喽,白头发多了
<2011-12-20 下午08时51分00秒 GMT+08:00> <Error> <HTTP Session> <BEA-100028> <Could not deserialize session data.
java.io.NotSerializableException: com.capinfo.service.impl.tcs.UnitUsersServiceImpl$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:422)
at java.util.TreeMap.writeObject(TreeMap.java:2243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Truncated. see log file for complete stacktrace
UnitUsersServiceImpl$1是
TreeMap<Long,TcsFunc> topTcsFuncList = new TreeMap<Long,TcsFunc>(new Comparator() {
public int compare(Object o1, Object o2) {
long l2 = Long.valueOf(String.valueOf(o2));
long l1 = Long.valueOf(String.valueOf(o1));
if(l2>l1)
return -1;
else if(l2<l1)
return 1;
else
return 0;
//return String.valueOf(o2).compareTo(String.valueOf(o1));
}
});
参考
http://www.tek-tips.com/viewthread.cfm?qid=1042413
Make sure the object you are putting into the session is serializable and also
the non-transient object it aggregates are also serializable.
If any of the non-transient objects in the entire object
graph are not serializable, you will receive this error message.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4330877
In order for classes such java.util.Treemap and java.util.TreeSet to be
serialized the Comparators(java.util.Comparator) also need to be serializable.
改成
TreeMap<Long,TcsFunc> topTcsFuncList = new TreeMap<Long,TcsFunc>(new MyComparator());
----
/**
* 因为用到这个比较器的TreeMap需要放到Session中
* 所以这个比较器也需要实现Serializable
*/
class MyComparator implements Comparator,Serializable{
public int compare(Object o1, Object o2) {
long l2 = Long.valueOf(String.valueOf(o2));
long l1 = Long.valueOf(String.valueOf(o1));
if(l2>l1)
return -1;
else if(l2<l1)
return 1;
else
return 0;
//return String.valueOf(o2).compareTo(String.valueOf(o1));
}
}
之前我们在Controller捕获异常的处理方式统一是throw new ServiceException(e.getMessage());
为了解决有异常时不能准确看到具体哪一行报错的问题
将ServiceException添加了一个两个参数的构造函数
将new ServiceException(e.getMessage()) 改成new ServiceException(e.getMessage(),e)
也就是将捕获到的Exception 也传进去
请大家以后使用new ServiceException(e.getMessage(),e)
ps -ef |grep java
kill -9 进程ID
cd /oracle/weblogic/user_projects/domains/base_domain/
nohup ./startWebLogic.sh &
tail -f nohup.out
加上排序后,发现第一页中的记录 会在第二页再次出现
解决办法
在order by 最后加上主键
参考:http://topic.csdn.net/u/20110726/14/b8fbdde2-3822-4e24-9e57-5566bfebcc92.html
表中添加了一个annotation
@org.hibernate.annotations.Entity(dynamicUpdate=true,dynamicInsert=true)
使Hibernate插入数据到数据库中时让字段默认值生效
关于dynamicUpdate、dynamicInsert属性的说明请参考:
http://blog.csdn.net/zhaoyh82/article/details/2514517
http://blog.csdn.net/foamflower/article/details/4370054
dynamic-insert 和 dynamic-update 是Hibernate mapping 配置文件中的一个可选特性。
dynamic-update 默认值为 false,可以在运行的时候构建 UPDATE SQL 语句,这个语句中只包含列中数据修改的的列,而不是所有的列。
dynamic-insert 默认值为 false,可以在运行的时候构建 INSERT SQL 语句,这个语句中只包含有数据的内容,换句话说如果某些列中不包含有数据,Hibernate 将不会将这些列构建到 SQL 脚本中。
hibernate有一个动态增加和动态更新功能。就是说hibernate生成的sql语句只set,有变化的字段。这样确实会从一定程度上提高性能。
可是动态更新的问题是查询和更新必须同时在一个相同的session中,否则hibernate无法判断这是不是一个相同的对象。可是实际上我们用更新 基本上都是查询出来之后,在前台做一些从新的赋值,在放到一个专有的update方法里更新。这样动态update的功能意义不大了。
怎么办呢?大家还记 得吗HibernateSessionFactory中的session都是单例的这样,我们要DAO层的查询和更新不关闭session.close, 将关闭session的任务交给业务逻辑层来完成不就解决了这个问题吗。
《Hiberante In Action》上介绍说 除非表里含有大字段或者字段数超过50个以上 否则不建议开启“动态更新”和“动态插入” 因为update xxxxx及insert xxxxx语句默认都是SessionFactory建立时就生成好的开启“动态”后就需要运行时现组装了 也需要挨个验证各属性是否改变。
这些操作也会浪费一定的效率会抵消“动态”的好处。
所以,这个特性对 Hibernate 来说作用不是非常明显。
1、让你的Controller继承AbstractController
2、在加载新增/修改页面的方法中调用saveToken(request,response);
3、在jsp页面中的<form>中加入一个hidden:(这是死的 不用任何修改)
<input type="hidden" name="TRANSACTION_TOKEN_KEY" id="TRANSACTION_TOKEN_KEY" value="${sessionScope.TRANSACTION_TOKEN_KEY}"/>
4、在保存方法中加入下面类似代码:
if(!super.isTokenValid(request)){
model.addAttribute(DataKey.MESSAGE, "对不起,你不能重复提交同一表单内容");
return "error";
}
==================
AbstractController:
public synchronized void saveToken(HttpServletRequest request,HttpServletResponse response) {
// setResponseNoCache(response); //
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute("TRANSACTION_TOKEN_KEY", token);
}
}
public synchronized void saveToken(HttpServletRequest request) {
HttpSession session = request.getSession();
String token = generateToken(request);
if (token != null) {
session.setAttribute("TRANSACTION_TOKEN_KEY", token);
}
}
/**
* 验证TOKEN
* @param request
* @return
*/
public synchronized boolean isTokenValid(HttpServletRequest request) {
// Retrieve the current session for this request
HttpSession session = request.getSession(false);
if (session == null) {
return false;
}
// Retrieve the transaction token from this session, and
// reset it if requested
String saved =
(String) session.getAttribute("TRANSACTION_TOKEN_KEY");
if (saved == null) {
return false;
}
// Retrieve the transaction token included in this request
String token = request.getParameter("TRANSACTION_TOKEN_KEY");
if (token == null) {
return false;
}
session.removeAttribute("TRANSACTION_TOKEN_KEY");
return saved.equals(token);
}
private synchronized String generateToken(HttpServletRequest request) {
HttpSession session = request.getSession();
try {
byte id[] = session.getId().getBytes();
byte now[] =
new Long(System.currentTimeMillis()).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return (toHex(md.digest()));
} catch (IllegalStateException e) {
return (null);
} catch (NoSuchAlgorithmException e) {
return (null);
}
}
private static String toHex(byte[] buffer) {
StringBuffer sb = new StringBuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++) {
sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
}
return sb.toString();
}
http://forum.springsource.org/showthread.php?48979-How-to-bind-String-to-java.sql.Timestamp
java.sql.TimeStamp is derived from java.util.Date. It shouldn't be hard to figure out how to handle that in the persistence layer- in fact I'm willing to bet that some persistence tools can handle that conversion automatically.
In regard to your command object, however, you have a tougher problem using TimeStamp. I'll explain why.
As I noted, TimeStamp is derived from java.util.Date. Spring has an out-of-the-box CustomDateEditor property editor that does conversions from Strings (like on a form filled out by a user) to java.util.Date. It also converts from java.util.Date back to String when a BindingResult is being used to re-populate form fields because the submission failed validation.
Now, for the CustomDateEditor to take the Date it has converted your String to and "jam" it into a TimeStamp field is not possible because it requires an explicit downcast. Spring does no such thing on your behalf. In fact- off the top of my head, I don't think such a downcast is even legal in Java- meaning you'd get an exception.
Do you see why I'm recommending going back to java.util.Date? It's the standard class used for transporting date (and time) information.
If you're really gung-ho about sticking with java.sql.TimeStamp, however, your next best bet is to create your own CustomTimeStampEditor. Basically crack open and copy the code for Spring's CustomeDateEditor and then modify it to suit TimeStamp.
$j("table.infoTable tr td").each(function(){var child = $j(this).children().eq(0);if(!child.is("input") && !child.is("select") && !child.is("textarea")&& !child.is("span")) $j(this).css('backgroundColor', '#e6eff3'); });
任何RuntimeException 将触发事务回滚,但是任何checked Exception 将不触发事务回滚
在dao 、servcie层都不要try catch,即使try catch 也要在catch中throw ServiceException供controler捕获
在controler中处理异常,所有catch都要ServiceException(自定义异常类 继承于RuntimeException)
参考:http://www.iteye.com/topic/34867
http://www.4ucode.com/Study/Topic/649831
@Controller
public class AbstractController {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Integer.class, null,
new CustomNumberEditor(Integer.class, null, true));
binder.registerCustomEditor(Long.class, null,
new CustomNumberEditor(Long.class, null, true));
binder.registerCustomEditor(byte[].class,
new ByteArrayMultipartFileEditor());
binder.registerCustomEditor(Date.class,new PropertyEditorSupport() {
public void setAsText(String value) {
try {
setValue(new SimpleDateFormat(Constants.DATE_FORMAT).parse(value));
} catch(ParseException e) {
setValue(null);
}
}
public String getAsText() {
return new SimpleDateFormat(Constants.DATE_FORMAT).format((Date) getValue());
}
});
}
}
packagecom.capinfo.webapp.handler;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
importorg.springframework.web.servlet.HandlerExceptionResolver;
importorg.springframework.web.servlet.ModelAndView;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.util.HashMap;
importjava.util.Map;
/**
* Created by IntelliJ IDEA.
* User: liuzhaochun
* Date: 11-8-12
* Time: 下午5:18
* 自定义异常处理类.
*/
public classMyHandlerExceptionResolver implements HandlerExceptionResolver {
private Log log =LogFactory.getLog(getClass());
public ModelAndViewresolveException(HttpServletRequest request,
HttpServletResponse httpServletResponse,
Object o, Exception ex) {
log.warn("Handle exception: "+ ex.getClass().getName());
Map model = newHashMap();
model.put("ex",ex.getClass().getSimpleName());
model.put("error",ex.getMessage());
return newModelAndView("error", model);
}
}
Jsp:error.jsp
<%@page language="java" pageEncoding="UTF-8"contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<%@ includefile="/include/meta.jsp"%>
</head>
<bodyid="error">
<div id="page">
<div id="content"class="clearfix">
<div id="main">
<h1>哦!</h1>
${ex}</br>
${error}
</div>
</div>
</div>
</body>
</html>
spring用到forward("/WEB-INF/jsp/*.jsp")
而forward当然是又要经过web.xml的映射的,
然后,在URL匹配时,
<url-pattern> / </url-pattern> 不会匹配到*.jsp,不会进入spring的DispatcherServlet类
<url-pattern> /* </url-pattern> 会匹配*.jsp,导致进入spring的DispatcherServlet 类,然后去寻找controller,接着找不到对应的controller所以报错。
总之,关于web.xml的url映射的小知识:
<url-pattern>/</url-pattern> 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url
<url-pattern>/*</url-pattern> 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)
SpringMVC 配置
1、 web.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<web-appxmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- Context Configuration locations forSpring XML files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/applicationContext-resources.xml
classpath:/applicationContext-dao.xml
classpath:/applicationContext-service.xml
</param-value>
</context-param>
<!--如果不定义webAppRootKey参数,那么webAppRootKey就是缺省的"webapp.root"。但最好设置,
以免项目之间的名称冲突。
定义以后,在Web Container启动时将把ROOT的绝对路径写到系统变量里。
然后log4j的配置文件里就可以用${webName.root }来表示Web目录的绝对路径,把log文件存放于webapp中。
此参数用于后面的“Log4jConfigListener”-->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
<!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond-->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<!--由Sprng载入的Log4j配置文件位置-->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Spring log4j Config loader
需要放在ContextLoaderListener之前
否则会提示log4j:WARN No appenders couldbe found for logger (org.springframework.web.context.ContextLoader)
-->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/index.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
</web-app>
1、maven的生命周期 resources:resources--->compiler:compiler-->resources:testResources-->compiler:testCompile-->surefire:test-->jar:jar
2、maven的传递性依赖,在我们的项目中只需定义直接的依赖,maven会自动搜索并添加所有依赖并处理之间的冲突,在maven库中不仅有jar文件还有一个定义了依赖关系的pom文件,以实现依赖的查找。
3、依赖分为测试范围test 、编译范围compile、provided 范围(只在编译时使用,部署时已由容器提供,Servlet API 第三方开源实现Apache Geronimo org.apache.geronimo.specs)
4、配置jetty插件
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</plugin>
</plugins>
5、maven 插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
好久没来写写了,时常过来逛逛,想想缺没什么说的
过年回来比较闲,在捣鼓 struts2 jpbm spring hibernate maven nexus
刚刚把nexus配好了,看到maven开始从nexus私服上下载了,舒心.....
蒸腾了大半天,竟然是因为搞错ordered group Repositories和available Repositories
我把所有的库托到了available Repositories 中,然后不停的ReIndex 晕死 就是不出来 哈哈
看来莺歌里氏很瓶颈啊
function Test(){
var num = 1;
AddNum = function(){num++;};
function getNum(){
alert(num);
}
return getNum;
}
var test = Test();
test();//1
AddNum();
test();//2
用闭包貌似可以模拟java中类的概念
Test是一个类
num是一个字段
getNum是get方法
AddNum是一个方法 这里不用var声明,为的是可以在全局访问
自己的一点理解,还在深入
AddNum是一个