1、书写规范
1 action - bean -strust
2 service- 事务-bean-注入action中
3 dao--继承HibernateDaoSupport--bean--注入service
2. 使用异步的方式加载客户级别和客户的来源
2.1使用的技术
前端使用JQuery的ajax技术
后端使用fastjson的jar包
导入fastjson的开发jar包fastjson-1.2.8.jarString s = JSON.toJSONString(集合)
String s = JSON.toJSONString(对象)
如果List集合中存入相同引用的对象
fastjson默认的情况下是进行循环检测的,去除掉死循环调用的方式
可以使用JSON.toJSONString(p,SerializerFeature.DisableCircularReferenceDetect) 去除循环检测,但是就会出现死循环的效果
最后可以使用注解:@JSONField(serialize=false)对指定的属性不转换成json
2.2 异步获取客户级别
Ajax代码
$(function(){
// 加载完成后使用ajax异步请求获得
var url = "${pageContext.request.contextPath}/dict_findByCode.action";
var param = {"dict_type_code":"006"};
$.get(url,param,function (data){
//$(data)表示将data(list)转成将jquery对象,然后做遍历
$(data).each(function(i,n){
//第一种方式是使用(i,n)i表示下表,n表示当前的对象==n.dict_type_name
$("#levelID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>")
//第二种方式是使用this,表示的是当前遍历的对象,相当于n;this.dict_type_name
})
},"json")
var param = {"dict_type_code":"001"};
$.get(url,param,function (data){
//$(data)表示将data(list)转成将jquery对象,然后做遍历
$(data).each(function(i,n){
//第一种方式是使用(i,n)i表示下表,n表示当前的对象==n.dict_type_name
$("#inductoryID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>")
//第二种方式是使用this,表示的是当前遍历的对象,相当于n;this.dict_type_name
})
},"json")
})
前端关键代码
<TD>客户名称:</TD>
<TD><INPUT class=textbox id=sChannel2
style="WIDTH: 80px" maxLength=50 name="cust_name"></TD>
<TD>客户级别:</TD>
<TD>
//关键的思想是level表示Customer实体类存储的字典表对象,通过.dict_id方式进行封装数据集
<select id="levelID" name="level.dict_id">
<option value="">--请选择--</option>
</select>
</TD>
<TD>客户行业:</TD>
<TD>
<select id="inductoryID" name="industry.dict_id">
<option value="">--请选择--</option>
</select>
</TD>
Action的代码
public String findByCode(){
List<Dict> list = dictService.findByCode(dict.getDict_type_code());
String jsonString = FastJsonUtil.toJSONString(list);
HttpServletResponse response = ServletActionContext.getResponse();
FastJsonUtil.write_json(response, jsonString);
return NONE;
}
* CustomerAction的分页查询的代码
public String findByPage(){
// 调用service业务层
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
// 拼接查询的条件
String name = customer.getCust_name();
if(name != null && !name.trim().isEmpty()){
criteria.add(Restrictions.like("cust_name", "%"+name+"%"));
}
// System.out.println(customer.getLevel().getDict_type_code());
Dict level = customer.getLevel();
if(level != null && !level.getDict_id().trim().isEmpty()){
criteria.add(Restrictions.eq("level.dict_id", level.getDict_id()));
}
Dict source = customer.getSource();
if(source != null && !source.getDict_id().trim().isEmpty()){
criteria.add(Restrictions.eq("source.dict_id", source.getDict_id()));
}
// 查询
PageBean<Customer> page = customerService.findByPage(pageCode,pageSize,criteria);
// 压栈
ValueStack vs = ActionContext.getContext().getValueStack();
// 栈顶是map<"page",page对象>
vs.set("page", page);
vs.set("cust_name", name);
return "page";
}
3、数据的回显
前端的代码
//1、数据的回显(txt 文本的显示)
<TD>客户名称:</TD>
<TD><INPUT class=textbox id=sChannel2
style="WIDTH: 80px" maxLength=50 name="cust_name" value="${ model.cust_name }"></TD>
//2、下拉菜单的回显示
//2.1级别选择
function(data){
$(data).each(function(i,n){
//第一种方式是使用(i,n)i表示下表,n表示当前的对象==n.dict_type_name
// 先获取值栈中的值,使用EL表达式
var vsId = "${model.level.dict_id}";
// 值栈中的id值和遍历的id值相同,让被选中
if(vsId == n.dict_id){
// JQ的DOM操作
$("#levelID").append("<option value='"+n.dict_id+"' selected>"+n.dict_item_name+"</option>");
}else{
$("#levelID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
}
//$("#levelID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>")
//第二种方式是使用this,表示的是当前遍历的对象,相当于n;this.dict_type_name
})
}
//2.2
$(data).each(function(i,n){
//第一种方式是使用(i,n)i表示下表,n表示当前的对象==n.dict_type_name
var vsId = "${model.industry.dict_id}";
// 值栈中的id值和遍历的id值相同,让被选中
if(vsId == n.dict_id){
// JQ的DOM操作
$("#inductoryID").append("<option value='"+n.dict_id+"' selected>"+n.dict_item_name+"</option>");
}else{
$("#inductoryID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>");
}
//$("#inductoryID").append("<option value='"+n.dict_id+"'>"+n.dict_item_name+"</option>")
//第二种方式是使用this,表示的是当前遍历的对象,相当于n;this.dict_type_name
})
4 保存客户动能
前提:javaBean是由get或者set方法决定的,和成员没有用。有get方法就可以当做属性,那么就能够进入值栈
4.1 页面跳转(menu->add)
前端-action-Struts2配置文件
<result name="addUI" >/jsp/customer/add.jsp</result> 为什么不能重定向到add页面上呢!!!!
4.2 添加功能
5、文件上传功能
5.1. 客户端三个注意事项
* method="post"
* enctype="multipart/form-data"
* <input type="file" name="myfile">
5.2 拦截器
* 提供 FileUpload 拦截器,用于解析 multipart/form-data 编码格式请求,解析上传文件的内容
* fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的
* 在Action中编写文件上传,需要定义三个属性
> 文件类型File ,属性名与表单中file的name属性名一致.
> 字符串类型String , 属性名:前段是name属性名一致 + ContentType;
> 字符串类型String , 属性名:前段是name属性名一致+FileName;
> 最后需要为上述的三个属性提供set方法。
> 可以通过FileUtils提供 copyFile 进行文件复制,将上传文件 保存到服务器端
5.3 文件上传存在的问题
* 先配置input逻辑视图
* 在页面中显示错误信息
* 文件上传的总大小默认值是2M,如果超过了2M,程序会报出异常。可以使用<s:actionError>来查看具体信息!
> 解决总大小的设置,找到常量:
* struts.multipart.parser=jakarta -- 默认文件上传解析器,就是FileUpload组件
* struts.multipart.saveDir= -- 文件上传的临时文件存储目录
* struts.multipart.maxSize=2097152 -- 文件上传的最大值(总大小),默认是2M
> 可以在struts.xml中设置常量,修改文件上传的默认总大小!!!
* <constant name="struts.multipart.maxSize" value="5000000"></constant>
5.4 通过配置拦截器 来设置文件上传你的属性
* 先在<action>标签中引入文件上传的拦截器
<interceptor-ref name="defaultStack">
<!-- 设置单个上传文件的大小 -->
<param name="fileUpload.maximumSize">2097152</param>
<!-- 设置扩展名 -->
<param name="fileUpload.allowedExtensions">.txt</param>
</interceptor-ref>
5.5 Action中的代码
/**
* 文件的上传,需要在CustomerAction类中定义成员的属性,命名是有规则的!!
* private File upload; // 表示要上传的文件
* private String uploadFileName; 表示是上传文件的名称(没有中文乱码)
* private String uploadContentType; 表示上传文件的MIME类型
* 提供set方法,拦截器就注入值了
*/
// 要上传的文件
private File upload;
// 文件的名称
private String uploadFileName;
// 文件的MIME的类型
private String uploadContentType;
public void setUpload(File upload) {
this.upload = upload;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
/**
* 保存客户的方法
* @return
* @throws IOException
*/
public String add() throws IOException{
if(uploadFileName != null){
// 打印
System.out.println("文件类型:"+uploadContentType);
// 把文件的名称处理一下
String uuidname = UploadUtils.getUUIDName(uploadFileName);
// 把文件上传到D:\\apache-tomcat-7.0.52\\webapps\\upload
System.out.println(uuidname);
// 上传的地址
String path = "D:\\JavaTomcat\\apache-tomcat-7.0.85\\upload\\";
// 创建file对象
File file = new File(path+uuidname);
// 简单方式
FileUtils.copyFile(upload, file);
// 把上传的文件的路径,保存到客户表中
customer.setFilePath(path+uuidname);
}
customerService.save(customer);
return "list";
}
6、删除客户
1. 先通过客户的主键查询出客户对象
2.根据客户对象进行删除,并且删除 upload文件
action代码
public String delete(){
// 删除客户,获取客户的信息获取到,上传文件的路径
customer = customerService.findById(customer.getCust_id());
// 获取上传文件的路径
String filepath = customer.getFilePath();
// 删除客户
customerService.delete(customer);
// 再删除文件
if(filepath!=null){
File file = new File(filepath);
if(file.exists()){
file.delete();
}
}
return "list";
}