在运行SSH项目时,调用dept_list.action和调用dept_delete.action时控制台并未打印异常。而调用add.action和edit.action却在控制台打印如下异常:
Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'x' on 'class com.zeng.ssh.oa.view.DepartmentAction: Error setting expression 'x' with value ['30', ]
Error setting expression 'x' with value ['30', ] - [unknown location]
at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:197)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:174)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:148)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:318)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:231)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:161)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:563)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:149)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: No object in the CompoundRoot has a publicly accessible property named 'x' (no setter could be found). - [unknown location]
at com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor.setProperty(CompoundRootAccessor.java:106)
at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2332)
at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
at ognl.SimpleNode.setValue(SimpleNode.java:301)
at ognl.Ognl.setValue(Ognl.java:737)
at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:234)
at com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:183)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:170)
... 62 more
Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'y' on 'class com.zeng.ssh.oa.view.DepartmentAction: Error setting expression 'y' with value ['17', ]
Error setting expression 'y' with value ['17', ] - [unknown location]
at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:197)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:174)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:148)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:318)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:231)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:161)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:563)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:149)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: No object in the CompoundRoot has a publicly accessible property named 'y' (no setter could be found). - [unknown location]
at com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor.setProperty(CompoundRootAccessor.java:106)
at ognl.OgnlRuntime.setProperty(OgnlRuntime.java:2332)
at ognl.ASTProperty.setValueBody(ASTProperty.java:127)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:220)
at ognl.SimpleNode.setValue(SimpleNode.java:301)
at ognl.Ognl.setValue(Ognl.java:737)
at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:234)
at com.opensymphony.xwork2.ognl.OgnlValueStack.trySetValue(OgnlValueStack.java:183)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:170)
... 62 more
departmentAction 代码:
package com.zeng.ssh.oa.view;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zeng.ssh.oa.domain.Department;
import com.zeng.ssh.oa.service.DepartmentService;
import com.zeng.ssh.oa.util.DepartmentUtils;
@Controller
@Scope("prototype")
public class DepartmentAction extends ActionSupport implements ModelDriven<Department> {
@Autowired
private DepartmentService departmentService;
/*
* 表单上有parentId这个name属性,实体类中并未封装这个parentId属性,而是封装Department parent属性,
* 在有些时候不希望在实体类中加入此属性. 此时,可以直接在Action中定义一个属性,并为之设置SET(修改)/GET(取值)方法
*/
private Long parentId;
private Department model = new Department();
@Override
public Department getModel() {
return model;
}
/** 查询所有 */
public String list() throws Exception {
// 0-1.查询所有部门
// List<Department> deptList = departmentService.findAll();
// 1-1.部门列表清单上查询顶级部门操作
List<Department> deptList = null;
if (parentId == null) {// 查询顶级部门
deptList = departmentService.findTopList();
} else {// 查询子级部门
// 开启了OpenInViewFilter懒加载过滤器,可以获取到关联对象的属性值。
deptList = departmentService.findChildList(parentId);
// 部门清单页面的【返回到上一级】 按钮的操作
// 当前是通过传递的parentId,查询到其对应的子级部门,再通过此parentId查询此对象的父级部门
Department parent = departmentService.getById(parentId);
ActionContext.getContext().put("parent", parent);
}
ActionContext.getContext().put("deptList", deptList);
return "list";
}
/** 根据ID删除 */
public String delete() throws Exception {
departmentService.delete(model.getId());
return "toList";
}
/** 添加页面 */
public String addUI() throws Exception {
// 1-1.取得部门列表,用于展示上级部门列表
List<Department> deptList = departmentService.findAll();
// 1-2.取得顶级部门列表,用于展示上级部门列表
// List<Department> topList = departmentService.findTopList();
// List<Department> deptList = DepartmentUtils.getAllDepartments(topList);
ActionContext.getContext().put("deptList", deptList);
return "saveUI";
}
/** 添加 */
public String add() throws Exception {
// 上级部门通过页面parentId值,查询到对应的Department对象,再把它设置到model中
System.out.println("---> save:parentId = " + parentId);
// 1-1.保存时设置部门值,部门值有可能为null,统一在baseDao中判断
Department parent = departmentService.getById(parentId);
model.setParent(parent);
// 0-1.保存model数据
departmentService.save(model);
return "toList";
}
/** 修改页面 */
public String editUI() throws Exception {
// 1-1.取得部门列表,用于展示上级部门
List<Department> deptList = departmentService.findAll();
// 1-2.取得顶级部门列表,用于展示上级部门列表
// List<Department> topList = departmentService.findTopList();
// List<Department> deptList = DepartmentUtils.getAllDepartments(topList);
//
ActionContext.getContext().put("deptList", deptList);
// 0-1.获取回显数据
Department department = departmentService.getById(model.getId());
System.out.println("id = " + model.getId());
System.out.println(department.getName());
// 0-2.把回显数据设置到栈顶
ActionContext.getContext().getValueStack().push(department);
// 1-2.设置当前的上级部门:上级部门有可能为null,代码必须要严谨
if (department.getParent() != null) {
// setParentId(department.getParent().getId());
// 数据回显,只要相对应的值有值即可回显
parentId = department.getParent().getId();
}
return "saveUI";
}
/** 修改 */
public String edit() throws Exception {
// 0-1.获取修改数据
Department department = departmentService.getById(model.getId());
// 0-2.设置修改数据
department.setName(model.getName());
department.setDescription(model.getDescription());
// 1-1.设置上级部门的所属部门
System.out.println("---> edit:parentId" + parentId);
department.setParent(departmentService.getById(parentId));// 设置所属的上级部门
// 0-3.保存修改数据
departmentService.update(department);
return "toList";
}
// -----
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
}
DepartmentServiceImpl代码:
package com.zeng.ssh.oa.service.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zeng.ssh.oa.dao.DepartmentDao;
import com.zeng.ssh.oa.domain.Department;
import com.zeng.ssh.oa.service.DepartmentService;
@Service
@Transactional
@SuppressWarnings("unchecked")
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentDao departmentDao;
@Autowired
private SessionFactory SessionFactory;
/**
* 查询顶级部门
* */
@Override
public List<Department> findTopList() {
return this.SessionFactory.getCurrentSession().createQuery(
"FROM Department d WHERE d.parent IS NULL")
.list();
}
/**
* 查询子级部门
* */
@Override
public List<Department> findChildList(Long parentId) {
return this.SessionFactory.getCurrentSession()
.createQuery(
"FROM Department d WHERE d.parent.id = ?")
.setParameter(0, parentId)
.list();
}
@Override
public List<Department> findAll() {
List<Department> deptList = departmentDao.findAll();
return deptList;
}
@Override
public void delete(Long id) {
departmentDao.delete(id);
}
@Override
public void save(Department model) {
departmentDao.save(model);
}
@Override
public Department getById(Long id) {
Department dept = departmentDao.getById(id);
return dept;
}
@Override
public void update(Department department) {
departmentDao.update(department);
}
}
BaseDaoImpl代码:
package com.zeng.ssh.oa.dao.impl;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.zeng.ssh.oa.dao.BaseDao;
@SuppressWarnings("unchecked")
public abstract class BaseDaoImpl<T> implements BaseDao<T> {
/* 使用session时,不再需要开事务,关事务。因为配置了事务 */
@Autowired
// 当子类使用组件注解,父类的属性也可以通过注入方式注入。
public SessionFactory sessionFactory;
public Class<T> clazz;// 在构造方法中初始化,泛型类
public BaseDaoImpl() {
// 使用反射技术得到T的真实类型
// 得到一个包含泛型信息的对象
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();// 获取当前new的对象的泛型父类类型
this.clazz = (Class<T>) pt.getActualTypeArguments()[0];// 获取第一个类型参数的真实类型,像Map<K,V>就有两个泛型参数。
System.out.println("clazz -----> " + clazz);
}
/**
* 获取当前可用的session
*
* @return
*/
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
@Override
public void save(T entity) {
getSession().save(entity);
}
@Override
public void delete(Long id) {
Object obj = getById(id);
// System.out.println("public method of delete: " + obj);
if (obj != null) {
// 这里要删除对象,传入对象的参数.
// 如果传入对象的ID(假如ID的数据类型是Long的话),则会报错.
// unknown entity: java.lang.Long(程序虽未报异常,但页面显示异常)
getSession().delete(obj);
}
}
@Override
public void update(T entity) {
getSession().update(entity);
}
@Override
public T getById(Long id) {
if (id == null) {
return null;
} else {
return (T) getSession().get(clazz, id);
}
}
/*
* HQL占位符可以使用?或使用:字符形式,?使用数字来定位,:字符使用字符来定位。
*
* @see com.zeng.ssh.oa.dao.BaseDao#getByIds(java.lang.Long[])
*/
@Override
public List<T> getByIds(Long[] ids) {
return getSession()//
.createQuery("FROM " + clazz.getSimpleName() + " WHERE id in (:ids)")//
.setParameterList("ids", ids).list();
}
@Override
public List<T> findAll() {
return getSession()//
.createCriteria(clazz)//
.list();
// clazz.getSimpleName()获取类的全限定名,包括包名
// return getSession().createQuery("FROM " +
// clazz.getSimpleName()).list();
}
}
struts.xml代码:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 配置为开发模式:true为开发模式 -->
<constant name="struts.devMode" value="true" />
<!--
目前的请求是URL-pattern=/*的模式,通过xx或xx.action或别的都可以访问
以下配置把扩展名配置为action,当请求是以.action时进行拦截,也为后续的过滤器做准备.
-->
<constant name="struts.action.extension" value="action"></constant>
<!-- 把主题配置为simple: -->
<constant name="struts.ui.theme" value="simple"></constant>
<package name="default" namespace="/" extends="struts-default">
<!--
method未写,使用默认的execute()方法
name:test(请求)
配置测试用的action,
当spring未与spring整合,class属性写类的全路径限定名
class="com.zeng.ssh.oa.test.TestAction"
当spring与struts2整合后,class直接写bean名
class="testAction"
-->
<action name="test" class="testAction">
<result name="success">/test_hello.jsp</result>
</action>
<!-- 岗位管理:RoleAction -->
<!--
action 属性
method 属性: 使用指定的[class=action]中对应的方法,也可以使用通配符“*”:{1}表示匹配name中的第一个“*”通配符。
name 属性: 表示请求,如果使用了通配如name=role_*,而method={1},使用role_list表示list方法,role_add表示add方法
class 属性: 表示Action。使用全路径限定名,如果与spring整合后,则可直接使用bean名
-->
<action name="role_*" class="roleAction" method="{1}">
<!--
result 属性
name 属性: 表示action返回的字符。
type 属性:指定redirect[重定向,也可以使用redirectAction],默认是转发,如果是返回JSON,则type=JSON。
-->
<result name="list">/WEB-INF/page/roleAction/list.jsp</result>
<result name="toList" type="redirectAction">role_list</result>
<result name="saveUI">/WEB-INF/page/roleAction/saveUI.jsp</result>
<!-- <result name="addUI">/WEB-INF/page/roleAction/addUI.jsp</result>
<result name="editUI">/WEB-INF/page/roleAction/editUI.jsp</result> -->
</action>
<!-- 部门信息 -->
<action name="dept_*" class="departmentAction" method="{1}">
<result name="list">/WEB-INF/page/deptAction/list.jsp</result>
<result name="saveUI">/WEB-INF/page/deptAction/saveUI.jsp</result>
<!-- 在add保存后跳转回当前页面,取得parentId值 -->
<result name="toList" type="redirectAction">dept_list?parentId=${parentId}</result>
</action>
</package>
</struts>
list.jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>部门列表</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="javascript" src="${pageContext.request.contextPath }/script/jquery.js"></script>
<script language="javascript" src="${pageContext.request.contextPath }/script/pageCommon.js" charset="utf-8"></script>
<script language="javascript" src="${pageContext.request.contextPath }/script/PageUtils.js" charset="utf-8"></script>
<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/style/blue/pageCommon.css" />
<script type="text/javascript">
</script>
</head>
<body>
<div id="Title_bar">
<div id="Title_bar_Head">
<div id="Title_Head"></div>
<div id="Title"><!--页面标题-->
<img border="0" width="13" height="13" src="${pageContext.request.contextPath }/style/images/title_arrow.gif"/> 部门管理
</div>
<div id="Title_End"></div>
</div>
</div>
<div id="MainArea">
<table cellspacing="0" cellpadding="0" class="TableStyle">
<!-- 表头-->
<thead>
<tr align=center valign=middle id=TableTitle>
<td width="150px">部门名称</td>
<td width="150px">上级部门名称</td>
<td width="200px">职能说明</td>
<td>相关操作</td>
</tr>
</thead>
<!--显示数据列表-->
<tbody id="TableData" class="dataContainer" datakey="departmentList">
<s:iterator value="#deptList" var="dept">
<tr class="TableDetail1 template">
<!-- 通过s:property标签中的value可以取到值,通过s:a中的value却无法取到值 -->
<%-- <td><s:property value="%{#dept.name}"/></td> --%>
<%-- <td><s:a action="dept_list?parentId=%{id}">${name }</s:a> </td> --%>
<!-- 通过这个嵌入s:property中就可以显示值 -->
<td>
<s:a action="dept_list?parentId=%{id}">
<s:property value="%{name}"/>
</s:a>
</td>
<td><s:property value="%{#parent.name}"/> </td><!-- 需要获取关联对象的属性值,需要开启懒加载 -->
<%-- <td>${parent.name } </td> --%>
<td>${description} </td>
<td><s:a action="dept_delete?id=%{id}&parentId=%{parentId}" onClick="return window.confirm('这将删除所有的下级部门,您确定要删除吗?')">删除</s:a>
<s:a action="dept_editUI?id=%{id}">修改</s:a>
</td>
</tr>
</s:iterator>
</tbody>
</table>
<!-- 其他功能超链接 -->
<div id="TableTail">
<div id="TableTail_inside">
<s:a action="dept_addUI?parentId=%{parentId}"><img src="${pageContext.request.contextPath }/style/images/createNew.png" /></s:a>
<!-- 【返回到上一级】部门操作:当前的子级列表是在父级部门列表下,要显示父级部门列表要找到父级的父级的部门ID, 储存值栈MAP中的值通过#parent.parent.id找到 -->
<s:if test="%{parentId != null}">
<%-- <s:if test="%{#parent != null}"> --%>
<s:a action="dept_list?parentId=%{#parent.parent.id}"><img src="${pageContext.request.contextPath }/style/blue/images/button/ReturnToPrevLevel.png" /></s:a>
</s:if>
</div>
</div>
</div>
<!--说明-->
<div id="Description">
说明:<br />
1,列表页面只显示一层的(同级的)部门数据,默认显示最顶级的部门列表。<br />
2,点击部门名称,可以查看此部门相应的下级部门列表。<br />
3,删除部门时,同时删除此部门的所有下级部门。
</div>
</body>
</html>
saveUI.jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>部门设置</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script language="javascript" src="${pageContext.request.contextPath }/script/jquery.js"></script>
<script language="javascript" src="${pageContext.request.contextPath }/script/pageCommon.js" charset="utf-8"></script>
<script language="javascript" src="${pageContext.request.contextPath }/script/PageUtils.js" charset="utf-8"></script>
<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/style/blue/pageCommon.css" />
</head>
<body>
<!-- 标题显示 -->
<div id="Title_bar">
<div id="Title_bar_Head">
<div id="Title_Head"></div>
<div id="Title"><!--页面标题-->
<img border="0" width="13" height="13" src="${pageContext.request.contextPath }/style/images/title_arrow.gif"/> 部门信息
</div>
<div id="Title_End"></div>
</div>
</div>
<!--显示表单内容-->
<div id=MainArea>
<s:form action="dept_%{id == null ? 'add' : 'edit'}">
<s:hidden name="id"></s:hidden>
<div class="ItemBlock_Title1"><!-- 信息说明<DIV CLASS="ItemBlock_Title1">
<IMG BORDER="0" WIDTH="4" HEIGHT="7" SRC="${pageContext.request.contextPath }/style/blue/images/item_point.gif" /> 部门信息 </DIV> -->
</div>
<!-- 表单内容显示 -->
<div class="ItemBlockBorder">
<div class="ItemBlock">
<table cellpadding="0" cellspacing="0" class="mainForm">
<tr><td width="100">上级部门</td>
<td>
<s:select name="parentId" cssClass="SelectStyle"
list="#deptList" listKey="id" listValue="name"
headerKey="" headerValue="== 请选择部门 ==">
</s:select>
<%-- <select name="parentId" class="SelectStyle">
<option value="0" selected="selected">请选择部门</option>
<option value="7">┠总经理室</option>
<option value="1">┠市场部</option>
<option value="2"> ┠咨询部</option>
<option value="3"> ┠招生部</option>
<option value="4">┠教学部</option>
<option value="5">┠后勤部</option>
</select> --%>
</td>
</tr>
<tr><td>部门名称</td>
<td><s:textfield type="text" name="name" cssClass="InputStyle"/> *</td>
</tr>
<tr><td>职能说明</td>
<td><s:textarea name="description" cssClass="TextareaStyle"></s:textarea></td>
</tr>
</table>
</div>
</div>
<!-- 表单操作 -->
<div id="InputDetailBar">
<input type="image" src="${pageContext.request.contextPath }/style/images/save.png"/>
<a href="javascript:history.go(-1);"><img src="${pageContext.request.contextPath }/style/images/goBack.png"/></a>
</div>
</s:form>
</div>
<div class="Description">
说明:<br />
1,上级部门的列表是有层次结构的(树形)。<br/>
2,如果是修改:上级部门列表中不能显示当前修改的部门及其子孙部门。因为不能选择自已或自已的子部门作为上级部门。<br />
</div>
</body>
</html>
异常引起原因 :
Caused by: No object in the CompoundRoot has a publicly accessible property named 'x' (no setter could be found). - [unknown location]
引起原因:
struts.xml配置中设置devMode=true时,会出现如上述异常。
当devMode=true时,配置为开发者模式。表单所有input标签中的name属性在action中都必须有对应的set/get方法,
无论是input为hidden设置的隐藏域 或者 通过URL传的参数值 。
解决方法:
1、配置<constant name="struts.devMode" value="false" />
2、为各个涉及到的参数设置set/get方法