后台常见报错处理和注意问题(一)
1、接口注入问题:
@Controller
@Scope("prototype")
public class GenuineManagementAction extends BaseAction {
private static final long serialVersionUID = -3797612994929924322L;
@Resource
private GenuineManagementService genuineManagementService;
@Resource//这样写是有问题的,去掉即可正常
private GenuineManagement genuineManagement;
}
@Resource代表注入,只有接口才能注入,而GenuineManagement 是一个实体类,所以加上@Resource 会报如下错误:
Unable to instantiate Action, genuineManagementAction,
No matching bean of type [com.vrv.paw.domain.GenuineManagement] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Unable to instantiate Action, genuineManagementAction, defined for 'genuineManagementAction_listUI' in namespace '/'Error creating bean with name 'genuineManagementAction': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.vrv.paw.domain.GenuineManagement] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(mappedName=, shareable=true, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)} - action - file:/E:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp4/wtpwebapps/JJFX/WEB-INF/classes/struts-extend.xml:420:89
at com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:318)
2、org.springframework.dao.InvalidDataAccessApiUsageException: The given object has a null identifier: com.paixie.domain.Users;
出现这个异常,一般来说主要修改时候主键没有传递或者name属性指定错误。
解决方案:你要把你的更新的实例的主键传过去,可以以hidden的方式传。
<!-- ID -->
<input id="id" type="hidden" name="controlMeasures.id" value="<s:property value='controlMeasures.id'/>">
3、service层的dao指向一定要正确,否则会出现问题,如果指向的是别的dao,那么在调用查询方法的时候,查询的表就是别的表了。
一方面是@Resource(name="controlMeasuresDao"),这个指向要正确
另一方面下面这种指向也是有问题的,指向的是BaseDao,而我们应该是要指向ControlMeasuresDao
@Service("controlMeasuresService")
@Transactional
public class ControlMeasuresServiceImpl extends BaseServiceImpl<ControlMeasures> implements ControlMeasuresService {
protected BaseDao<ControlMeasures> controlMeasuresDao;
public BaseDao<ControlMeasures> getControlMeasuresDao() {
return controlMeasuresDao;
}
@Resource(name="controlMeasuresDao")
public void setControlMeasuresDao (BaseDao<ControlMeasures> controlMeasuresDao) {
this.controlMeasuresDao = controlMeasuresDao;
this.baseDao = controlMeasuresDao;
}
@Override
public ControlMeasures queryByConId(Integer id) {
return baseDao.queryById(id);
}
}
需要修改一下,要向下面这样修改,才会指向的是ControlMeasuresDao
public class ControlMeasuresServiceImpl extends BaseServiceImpl<ControlMeasures> implements ControlMeasuresService {
protected ControlMeasuresDao controlMeasuresDao;
@Resource(name="controlMeasuresDao")
public void setGenuineManagementDao(ControlMeasuresDao controlMeasuresDao) {
this.controlMeasuresDao = controlMeasuresDao;
this.baseDao = controlMeasuresDao;
}
@Override
public void deleteGmId(Integer id) {
controlMeasuresDao.deleteGmId(id);
//如果指向不对的话,那么在这里这个deleteGmId就会提示你要在BaseDao里面去新建,而实际上我们是要在ControlMeasuresDao里面去建
}
}
如果指向不对的话,那么在这里这个deleteGmId就会提示你要在BaseDao里面去新建,而实际上我们是要在ControlMeasuresDao里面去建
4、修改数据的时候,调用edit方法一定要传个id过去
//修改规则库管理
function editControl(){
var selectRows = $("#ruleManagementTable").datagrid('getSelections');
if(selectRows.length > 1){
showMsg("只能选择一个修改!");
return false;
}
showWindow("修改规则库管理","genuineManagementAction_editUI.do?controlMeasures.id="+selectRows[0].id,"500","380",true);
}
如果不传id,那么下面是获取不到那个实体类的
//修改规则库UI
public String editUI(){
if(controlMeasures != null){
controlMeasures = controlMeasuresService.queryById(controlMeasures.getId());
}
return RETURN_EDITUI;
}
5、两页面之间传值:
(1)首先做为参数传给后台
function addControl(){
var policyName = $("#strategyName").val();
showWindow("新建规则库管理","genuineManagementAction_addUI.do?genuineManagement.policyName="+policyName,"500","380",true);
}
(2)其次在addUI方法上把值set进去
public String addUI(){
if(genuineManagement.getPolicyName() != null && !"".equals(genuineManagement.getPolicyName())){
getRequest().setAttribute("policyName", genuineManagement.getPolicyName());
}
return RETURN_ADDUI;
}
(3)在此在addUI页面上把值获取,并赋予form表单里的隐藏域。
var policyName = '<s:property value="genuineManagement.policyName"></s:property>';
$("#policyName").val(policyName);
<form id="controlMeasures_add">
<input type="hidden" id="policyName" name="controlMeasures.policyName"
注意:获取的时候是原实体的属性,传值的时候是目标实体的属性,如上面标红初。
这样在获取controlMeasures实体的时候,就可以获取到传过来的policyName了
6、使用form表单提交的时候,form表单自动会提交各参数,如果url路径后面加了参数,那么会先复制url的参数,然后form表单里默认的参数,会覆盖url路径后面的参数
$("#buttonSubmit").click(function(){
debugger
var softDisplayName = $("#softDisplayName").val();
var softId = $("#softDisplayName option[value='" + softDisplayName + "']").attr("softId");
var version = $("#version").val(),
type = $("#type").val(),
serialNumber = $("#serialNumber").val();
$("#genuineSerialNumberManagementAction_add").form("submit",{
method : "POST",
url : "genuineSerialNumberManagementAction_add.do?disc=genuineSerialNumberManagement_add&genuineSerialNumberManagement.softDisplayName="
+ escape(escape(softDisplayName)) + "&genuineSerialNumberManagement.version=" + escape(escape(version))
+ "&genuineSerialNumberManagement.serialNumber=" + escape(escape(serialNumber))
+ "&genuineSerialNumberManagement.type=" + type
+ "&genuineSerialNumberManagement.softId=" + softId,
timeout : 3000000,
success :
如上面问题,如果form表单里面没给$("#softId")赋值,那么form表单默认的softId参数就是空的,那么传到后台就始终获取不到softId的值,需要修改下:
$("#buttonSubmit").click(function(){
var softDisplayName = $("#softDisplayName").val();
var softId = $("#softDisplayName option[value='" + softDisplayName + "']").attr("softId");
$("#softId").val(softId);
$("#genuineSerialNumberManagementAction_add").form("submit",{
method : "POST",
url : "genuineSerialNumberManagementAction_add.do",
timeout : 3000000,
success :
这样既可获取到,记住:提交采用form形式无需加url参数。
7、为防止点击页面出现404错误,需要在 struts-extend.xml 文件上加上下面配置:
<!-- 正版化统计 -->
<action name="genuineManagementStaticAction_*" class="genuineManagementStaticAction" method="{1}">
<result name="{1}">/WEB-INF/pages/genuineManagementStaticAction/{1}.jsp</result>
<result name="toList" type="redirectAction">/genuineManagementStaticAction_listUI.do</result>
</action>
8、org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: . 异常处理方法
public void list() {
try {
HQLBuilderUtil hql = new HQLBuilderUtil(Software.class);
if(software!=null && software.getSoftId()!=null && !"".equals(software.getSoftId())){
Integer softId = software.getSoftId();
hql.addWhereClause(" this.softId=? ", softId);
}
Integer pcCount = pcInfoService.queryAll().size();//PC总数
GridData<Software> reportlogs = softwareService.getPageView(hql, getPageNum(), getPageSize());
List<Software> list = reportlogs.getRows();
for (int i = 0; i < list.size(); i++) {
//取安装数
Integer installCount = genuineManagementStaticService.queryInstallNum(list.get(i).getSoftId());
NumberFormat numberFormat = NumberFormat.getInstance();
// 设置精确到小数点后2位
numberFormat.setMaximumFractionDigits(2);
String result = numberFormat.format((float) installCount / (float) pcCount * 100) + "%";
list.get(i).setInstallNum(installCount);
list.get(i).setInstallPersent(result);
//取正版数
Integer genuine = 1;
Integer genuineCount = genuineManagementStaticService.queryGenuineNum(genuine, list.get(i).getSoftId());
Integer softCount = genuineManagementStaticService.querySoftNum(list.get(i).getSoftId());
NumberFormat numberFormatGenuine = NumberFormat.getInstance();
// 设置精确到小数点后2位
numberFormat.setMaximumFractionDigits(2);
String genuineResult = numberFormatGenuine.format((float) genuineCount / (float) softCount * 100) + "%";
list.get(i).setGenuineNum(genuineCount);
list.get(i).setGenuinePersent(genuineResult);
//取最新版本
GenuineManagementStatic gms = genuineManagementStaticService.queryNewVersion(list.get(i).getSoftId());
list.get(i).setVersion(gms.getVersion());
}
print(ActionUtil.jsonObj(reportlogs));
} catch (Exception e) {
e.printStackTrace();
}
}
当上面 hql.addWhereClause(" this.softId=? ", softId); 如果没有 =? 会报错误:
1147240 [http-bio-8080-exec-4] ERROR org.hibernate.hql.PARSER - <AST>:1:55: unexpected AST node: .
org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: . near line 1, column 55 [ FROM com.vrv.paw.domain.Software this WHERE this.softId ]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
解决方法:加上 =? 来与参数对应
9、数据库执行的一个小问题,如果没有executeUpdate()只是设置了执行语句,并没有执行,所以发现删除不了数据库的内容,其实是这个小问题的影响
同时createSQLQuery的执行方法还不一样,如果是createSQLQuery就会报错。
@Override
public void deleteGmId(Integer gmId) {
this.getSession().createQuery(" DELETE FROM " + this.clazz.getName() + " WHERE gmId =(:gmId)")
.setParameter("gmId", gmId)
.executeUpdate();
}
严重: Servlet.service() for servlet jsp threw exception
org.apache.jasper.JasperException: /show.jsp(87,33) quote symbol expected
org.apache.jasper.JasperException: /show.jsp(87,33) quote symbol expected这一行表明 : show.jsp 的87行33列少了一个 引号,行数可能有偏差,我的偏差了一行,实际是 88行少了一个引号~把引号加上就 OK啦,特别是使用struts标签的时候,要特别注意。