Chinaunix首页 | 论坛 | 博客
  • 博客访问: 715128
  • 博文数量: 147
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 10:36
文章分类

全部博文(147)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(110)

我的朋友

分类: Java

2009-05-17 19:06:18

1.客户端传递过来的参数,会寻找action中set方法和参数名一样的,和属性名没有关系
在转发到的结果页面也可以这样获得:
${requestScope.username}
${requestScope.password}
或者
<%request.getParameter("username")%>
2.类型转换
  比如我们注册表单的时候,如果不类型转化的话,那么在action中要有对应的属性,进行转化,我们可以在action中有个User类就行了!
"hello".equals(this.getUsername().trim());
类型转换的步骤:
前台输入一个数值,用,隔开,将它转化为point类型的
1.页面

2.类:
public class Point{
private int x;
private int y;
.....
//set和get方法
}
3.public class PointConverter extends DefaultTypeConverter{
//转换有两种:
//1.自定义类型到string类型转化
//1.string到自定义类型转化
public Object convertValue(Map context,Object value,Class toType){
//toType是要转换成的类型,客户端String到自定义类型转换
//value是要转换的值
//从客户端到服务器端的转化
if(Point.class==toType){
  Point point=new Point();
  //页面可能有几个叫做point的input,所以这里要转换成数组
  String[] str=(String[])value;
  String[] paramValues=str[0].split(",");
  int x=Integer.parseInt(paramValues[0]);
  int y=Integer.parseInt(paramValues[1]);
 
  point.setX(x);
  point.setY(y);
  retunr point;
}
//如果目标类型是String,就是向页面显示数据,从服务器端到客户端
if(String.class==toType){
 Point point=(Point)value;
 int x=point.getX();
 int y=point.getY();
 
 String result="[x="+x+", y="+y+"]";
 return result;
}
return null;
}
}
4.public class PointAction extends ActionSupport{
private Point point;
private Date date;//struts2自动进行转化2007-12-06
......
}
4.PointAction-conversion.properties
(该文件和PointAction文件在同一个包下面)
//对哪个属性进行类型转化
point(属性名字)=com.test.converter.PointConverter
5.页面:

如果在多个action中都有Point,那么是否都的写
**Action-conversion.properties????
,不需要!上面的是局部类型转换,下面写全局类型转换 对系统里面多有符合类型的action都要转换!
步骤:
在classpath下面建立配置文件:
xwork-conversion.properties
com.test.bean.Point=com.test.converter.PointConverter
 
strtus2本身提供了一个类型类型转换:
继承StrutsTypeConverter
public class PointConverter extends StrutsTypeConverter{
public Object convertFromString(Map context,String[] values,Class toClass){
 Point point=new Point();
  
  String[] paramValues=values[0].split(",");
  int x=Integer.parseInt(paramValues[0]);
  int y=Integer.parseInt(paramValues[1]);
 
  point.setX(x);
  point.setY(y);
  retunr point;
}
public String convertToString(Map context,Object o){
Point point=(Point)o;
 int x=point.getX();
 int y=point.getY();
 
 String result="[x="+x+", y="+y+"]";
 return result;
}
}
 

现在需要集合类型的:
public class PointAction extends ActionSupport{
private List point;
...........
}
public class PointConverter extends StrutsTypeConverter{
public Object convertFromString(Map context,String[] values,Class toClass){
 List list=new ArrayList();
  for(String value:values)
  {String[] paramValues=values[0].split(",");
  int x=Integer.parseInt(paramValues[0]);
  int y=Integer.parseInt(paramValues[1]);
 
  point.setX(x);
  point.setY(y);
  list.add(point);
  }
 return list;
}
public String convertToString(Map context,Object o){
List list=(List)o;
StringBuilder sb=new StringBuilder();
sb.append("[");
for(Point point:list){
 int x=point.getX();
 int y=point.getY();
 sb.append("x=").append(x).append(",y=").append(y);
 }
sb.append("]");
return sb.toString();
}
}
还支持这样的类型转换


action中:
private Point point;
不需要类型转化!显示会调用point的tostring方法;
采用这种方式,point要构造无参数的构造方法
 

2.验证框架:
输入校验(检验用户输入的信息是否符合要求):
输入检验是在类型转换基础之上的
struts表单标签库已经内置了基本的验证机制,比如:action中是int age;页面中输入字符串,那么框架在转化的是就会出现错误,表单中就会提示输入错误,但是那种提示信息不好看!
一.表单 不用struts2标签 进行输入校验
   action继承ActionSupport重写validate
   同样如果输入的类型不匹配,struts2先进行类型转化时候就会出错,然后校验 ,仍然会有标签自带的错误信息提示,而且表单中的内容会消失,要不想让他消失:
这种方式比较麻烦:那么我们用struts2表单标签就可以解决这样的问题
如果客户端给age提供abc的值,那么struts2不能进行类型转换,那么框架自动生成一条错误信息,并且将错误信息放在addFieldError里面,且将提交的值为0
那么怎么替换框架原有的提示信息呢?
在struts框架中要使用的常量,在struts.xml中配置:


message.properties文件放在classpath下面
#类型转化出问题的话就会是下面的提示信息了
xwork.default.invalid.fieldvalue={0} error
参数0就是表单中name的值
上面是一个全局的验证。
下面是个局部的验证(验证某一个action):
PointAction(action名字).properties文件和action在同一个包下面:
#类型转换发生错误 int会为0,String会为null
invalid.fieldvalue.age(action中的属性)=age conversion error

框架先是进行类型转化(如果类型转化错误,就会把错误信息保存在addFieldError里面,但是错误信息提示不友好,怎样修改 如上面) 然后在进行校验!

要想有中文提示信息:
那么用jdk带的native2ascii工具转化
native2ascii test.txt(含有中文) test.properties  用test.properties这个文件!

那么总结类型转换和输入校验的流程:
1.首先strtus2对客户端传来的数据进行类型转换
2.类型转换完毕后在进行输入校验
3.如果类型转换和输入校验都没有错误发生,那么进入execute方法
注意:如果类型转换不成功也同样进行输入校验

校验错误有2种:addFiekdError(属性级别错误)和addActionError(action级别错误)
action级别的错误
在表单上面增加:
field级别的错误,struts2表单标签就可以显示错误信息
  
theme属性定义为simple,就是没有样式的,不会为我们生成表格,这样我们就可以用自己的css来美化了
注意:::如果action中的方法为abc,那么验证方法为:validateAbc()
校验执行顺序:
  validateAbc  validate abc
如果不想validate那么有两种解决办法:
1.不写validate方法
2.不写validate方法,增加validateExecute方法
上面都是写代码来验证的,那么下面讲框架验证,通过xml文件来验证:
步骤:
1.配置文件(针对每一个action)(参数参考xwork-2.0.4.jar下面的com.......validators)
 文件名 PointAction-validation.xml
 开头的一些信息从struts2下载的包中的例子中拷贝
 
  
          true
          username should not be blank!
     
     
          true
          6
          10
          username should be between ${minLength} and ${maxLength}
     

  

  
          true
          password should not be blank!
     
     
          true
          6
          10
          password should be between ${minLength} and ${maxLength}
     

  

  
          true
          repassword should not be blank!
     
     
          true
          6
          10
          repassword should be between ${minLength} and ${maxLength}
     

  

  
          true
          age should not be blank!
     
     
          1
          150
          age should be......
     
     
  

  
          true
          birthday should not be blank!
     
               
          2001-01-01
          2003-12-31
          birthday should be between ${min} and ${max}
     

  

  
          true
          birthday should not be blank!
     
               
          2005-01-01
          2007-12-31
          graduation should be between ${min} and ${max}
     

  

 

 
客户端校验:
1.form的主题(theme)不能设置为simple
2.form的validate属性设置为true
那么需要上面的xml配置文件!建议不要使用struts2的客户端校验
上面是针对action中的所有属性进行校验
那么针对某个方法进行校验?
PointAction-abc-validattion.xml 不过先校验这个文件,然后在校验
PointAction-validattion.xml 然后在validate方法,
建议对于不同的方法,写不同的检验文件

3.拦截器(Intersptor):
  我的博客......
  方法拦截器MehtodFilterInterceptor
 
 
     
     
          方法名,方法名
          方法名,方法名
     

     
  
 
4.文件的上传和下载:
实例一:
不用struts2,用apache的fileupload组件上传:
jsp页面:

  username:
  password:
  file1:
  file2:

servlet类:
public class UploadServlet extends HttpServlet{
public void post(....){
DiskFileItemFactory factory=new DiskFileItemFactory();
//获得绝对目录
String path=request.getRealPath("/upload");
//上传文件大的话,就会先存储在临时存储目录,然后在转到上传目录
factory.setRespository(new File(path));
//设定上传文件的大小,如果小于等于这个大小,就保存在内存里面,然后转到上传目录,如果大于这个大小,先存储到临时目录,然后在转到上传目录
factory.setSizeThreshold(1024*1024);
//创建实例
ServletFileUpload upload=new ServletFileUpload(factory);
try{
 //返回客户端上传的文件列表
 List list=upload.parseRequest(request);
 for(FileItem item:list){
   if(item.isFormField()){//是一般的类型
      //获得表单中定义的name
      String name=item.getFiledName();
      //获得用户输入的内容value
      String value=item.getString("gbk");
      request.setAttribute(name,value);     
   }else{
       //获得表单中定义的name
      String name=item.getFieledName();
      //获取上传文件的名字
      String value=item.getName();
      int start=value.lastIndexOf("\\");
      String fileName=vlaue.substring(start+1);
      request.setAttribute(name,fileName);
    
      item.write(new File(path,fileName));
     或者
    //  OutputStream os=new FileOutputStream(new File(path,fileName));
    //  InputStream is=item.getInputStream();
   //   byte[] buffer=new byte[400];
   //   int length=0;
   //   while((length=is.read(buffer))>0){
    //    os.write(buffer,0,length);
   //   }
   //   os.close();
   //  is.close();
   }
 }
}catch(Exception e){
....
}
request.getRequestDispatcher("upload/reault2.jsp").forward(request,response);
}
}
实例二:
struts2实现文件上传:
上传一个文件:
public class UploadAction{
private String username;
private String password;
private File file;
private String fileFileName;
private String fileContentType;
//属性的get和set方法
.........
public String execute(){
    InputStream is=ne FileInputStream(file);
    String root=ServletActionContext.getRequest.getRealPath(/upload);
    File destFile=new File(root,this.getFileFileName());
    OutputStream os=new FileOutputStream(destFile);
 
   byte[] buffer=new byte[400];
    int length=0;
     while((length=is.read(buffer))>0){
     os.write(buffer,0,length);
    }
    os.close();
   is.close();
   return "success";
}
}
解决中文在struts.xml中加上:

用户上传固定的几个文件:
public class UploadAction{
private String username;
private String password;
private List file;
private List fileFileName;
private List fileContentType;
//属性的get和set方法
.........
public String execute(){
  for(int i=0;i    InputStream is=ne FileInputStream(file.get(i));
    String root=ServletActionContext.getRequest.getRealPath(/upload);
    File destFile=new File(root,this.getFileFileName().get(i));
    OutputStream os=new FileOutputStream(destFile);
 
   byte[] buffer=new byte[400];
    int length=0;
     while((length=is.read(buffer))>0){
     os.write(buffer,0,length);
    }
    os.close();
   is.close();
 }
   return "success";
}
}
页面中有3个:都是

用户上传任意多个文件
jsp页面

  file
 

  

js代码:
function addMore(){
 var td=document.getElementById("more");
 var br=document.createElement("br");
 var input=document.createElement("input");
 var button=document.createElement("input");
 input.type="file";
 input.name="file";
 button.type="button";
 button.value="Remove";
 button.onclick=function(){
   td.removeChild(br);
   td.removeChild(input);
   td.removeChild(button);
 }
 td.appendChild(br);
 td.appendChild(input);
 td.appendChild(button);
}
Action服务器端代码:不用修改
限制用户上传的格式:
 
     409600//每个文件的大小
    
     application/vnd.ms-powerpoint
   
  

想改变错误提示信息:


message.properties文件放在classpath下面
#类型转化出问题的话就会是下面的提示信息了
struts.messages.error.content.type.not.allowed=the fiel type is error
struts.messages.error.file.too.large=the file is too large
 
用户下载:
public class DownloadAction{
//和配置文件的inputName同样
public InputStream getDownloadFile(){
  return ServlerActionContext.getServletContext.getResourceAsStream("/upload.struts.ppt");
}
public String execute(){
return success;
}
}
配置文件struts.xml

 
     application/vnd.ms-powerpoint
     filename="struts2.ppt"
     downloadFile    
 


对于下载的文件名,下载的文件类型都是在struts.xml文件中配置的,如果有不同的类型的文件要提供给用户下载,那么这种方式显然有失灵活性。
   为了动态的设置文件类型和下载的文件名,我们可以编写 一个拦截器,在action执行完毕,result执行之前,动态添加StreamResult参数。
public class FileDownloadInterceptor extends Abstracterceptor{
public String interceptor(ActionInvocation invocation)throws Exception{
incocation.addPreResultListener(new PreResultListener(){
public void beforeResult(ActionInvocation invocation,String resultCode){
Map resultMap=invocation.getProxy().getConfig().getResults();
ResultConfig finalResultConfig=resultMap.get(resultCode);
//为了简单起见,我们硬编码了下载文件的类型和下载文件名,实际应用中你可以读取数据库或者配置文件来获取下载文件的信息
finalResultConfig.addParam("contentType",application/zip);
fianlResultConfig.addparam("contentDisposition","attachment;filename=\"abc.zip\"");
}
});
return invocation.invoke();
}
}

4.国际化:
有几方面:
  页面的国际化
  action提示信息的国际化
  类型转化提示信息的国际化
  输入校验提示信息的国际化
java语言对于国际化的支持 
  ResouceBundle类 Locale类
如何来获得当前系统jdk里面的国家和语言的支持
public class Main{
public static void mian(Srting args[]){
Local[] locales=Locale.getAvailableLocales();
for(Locale locale:locales){
  System.out.println(local.getDisplayCountry()+":"+local.getCountry());
  System.out.println(local.getDisplayLanguage()+":"+local.getLanguage());
 }
}
}
国际化文件支持文件(classpath下面)
命名:baseName_language_country
英文文件:hellofile_en_US.properties
hello=hello:{0}(动态参数)
中文文件:hellofile_zh_CN.properties
hello=\u4f60\u597d
对于中文文件,要转化。
国际化方法:
public class Main{
public static void mian(Srting args[]){
//Local locale=Locale.getDefault();//取得中文
Local locale=Locale.US
ResourceBundle bundle=ResourceBundle.getBundle("hellofile",locale);
String value=bundle.getString("hello");
System.out.println(value);
}
}
国际化文件中有参数
public class Main{
public static void mian(Srting args[]){
Local locale=Locale.getDefault();//取得中文
ResourceBundle bundle=ResourceBundle.getBundle("hellofile",locale);
String value=bundle.getString("hello");
String result=MessgeFormat.format(value,new Object[]{"北京"});
System.out.println(result);
}
}
在web中国际化
国际化文件:
messge_en_US.properties
addUser=Add User Infomation
message_zh_CN.properties
addUser=........
struts.xml

jsp页面

action中的国际化
国际化文件:放在classpath下面
messge_en_US.properties
addUser=Add User Infomation
username.invalid=......
message_zh_CN.properties
addUser=username "{0}" invalid
username.invalid=......
struts.xml


action的validate方法
public void validate(){
....
this.addActionErroe(this.getText("username.invalid"));
....
}
含有参数:
public void validate(){
....
List list=new ArrayList();
list.add(username);
this.addActionErroe(this.getText("username.invalid"),list);
....
}

输入校验国际化:

          true
         
     
     
          true
          6
          10
          username should be between ${minLength} and ${maxLength}
     


资源文件如果不可能只有一个,有包级别的和类级别的
 包级别的资源文件放在包下面:
 package_en_US.properties
 package_zh_CN.properties
发生错误会先从包级别找
 类级别的资源文件和action
 RegisterAction_en_US.properties
 RegisterAction_zh_CN.properties

struts2的深入探索:
 
模型驱动:将属性封装在一个JavaBean里面为不是在action中
public class User{
private String username;
private String password;
.....
//属性的get和set方法
.......
}
public class RegisterAction extends ActionSupport implements ModelDriven{
private User user=new User();
public User getModel(){
return user;
}
public String execute(){
.............
}
}
推荐使用属性驱动方式!

Preparable接口,在执行action方法之前先去执行的一些动作
public class MianAction implements Preparable{
public void prepare(){
.......
}
........
}

禁止表单重复提交:
首先:

   //增加这个标签就可以了
.........

然后:

...
.....



页面中显示重复提交不成功信息

action中使用Cookie
Cookie cookie=new Cookie("username",this.getUsername());
cookie.setMaxAge(1000);
response.addCookie(cookie);
只要是重定向,原来保存在request中的数据全部消失

struts2整合JFreeChat
首先下载jar包:选择
  jfreechat-1.0.9.jar
  jcommon.jar
  可以查看demo,在下载的包下面的jfreechat-demo.jar 双击  可以执行

体验JFreechat
饼图:::::
public class Main{
public staic void main(String args[]){
 //定义饼图数据集
 DefaultPieDataset dpd=new DefaultPieDataset();
 //设置数据
 dpd.setValue("管理人员",25);
 dpd.setValue("市场人员",25);
 dpd.setValue("开发人员",45);
 dpd.setValue("其他人员",10);
 //工厂创建
 JFreeChart chart=CharFactory.createPieChart("某公司人员组织结构图",dpd,true,true,true);
 //JFreeChart chart=CharFactory.createPieChart3D("某公司人员组织结构图",dpd,true,true,true);
 //用swing显示出来
 ChartFrame chartFrame=new ChartFrame("某公司的人员组织图",chart);
 chartFrame.pack();
 chartFrame.setVisable(true);
}
}
将图表对象转换成图片
public class Main{
public staic void main(String args[]){
 //定义饼图数据集
 DefaultPieDataset dpd=new DefaultPieDataset();
 //设置数据
 dpd.setValue("管理人员",25);
 dpd.setValue("市场人员",25);
 dpd.setValue("开发人员",45);
 dpd.setValue("其他人员",10);
 //工厂创建
 JFreeChart chart=CharFactory.createPieChart("某公司人员组织结构图",dpd,true,true,true);
//设置标题
chart.setTitle(new TextTitle("hello",new Font("宋体",Font.BLOD,22)));
LegendTitle legend=chart.getLengend(0);
legend.setItemFont(new Font("宋体",Font.BLOD,22));
PiePlot plot=(PiePlot)chart.getPlot();
plot.setLableFont(new Font("宋体",Font.BLOD,22));
//输出为图片
OutputStream os=new FileOututStream("company.jpeg");
ChartUtilities.vriteChartAsJPEG(os,chart,1000,800);
os.close();
}
}
如何在jsp里面生成JFreechat图片
首先在web.xml中加入:
 
      DisplayChart
      org.jfree.chart.setvlet.DisplayChart
 

 
      DisplayChart
      /servlet/DispalyChart
 

jsp页面:
 <%
 //定义饼图数据集
 DefaultPieDataset dpd=new DefaultPieDataset();
 //设置数据
 dpd.setValue("管理人员",25);
 dpd.setValue("市场人员",25);
 dpd.setValue("开发人员",45);
 dpd.setValue("其他人员",10);
 //工厂创建
 JFreeChart chart=CharFactory.createPieChart("某公司人员组织结构图",dpd,true,true,true);
//输出为图片
String filename=ChartUtilities.vriteChartAsJPEG(chart,1000,800,session);
//文件在服务器上的地址
String url=request.getContextPath()+"DisplayChart?filename="+filename;
 %>
 
struts2整合
jsp页面:
 
 
 
Action类:
public class Viewresult extends ActionSupport{
private JFreeChart chart;
private List interest;
...get和set
public String execute(){
 super.execute();
}
//把下面的这方法放在业务逻辑里面,别放在这里
public void increaseResult(List list){
ActionContext context=ActionContext.getContext();
Map map=context.getApplication();
for(String str:list){
  if(null==map.get(str)){
    map.put(str,1);
  }else{
    map.put(str,(Integer)map.get(str)+1);
  }
}
//产生柱状图
private CategoryDataset getDataset(){
  DefaultCategoryDataset dataset=new DefaultCategoryDataset();
  this.increaseResult(this.getInterest());
  ActionContext context=ActionContext.getContext();
  Map map=context.getApplication();
  dataset.setValue((Integer)map.get("football"),"","足球");
  dataset.setValue((Integer)map.get("basketball"),"","篮球");
  .....
  return dataset;
}
//生产JFreechat对象
public JFreeChat getChart(){
chart=ChartFactory.createBarChart("兴趣统计结果","项目","结果",this.getDataset(),PlotOrientation.VERTICAL,false,false,false);
 
CategoryPlot plot=(CategoryPlot)chart.getPlot();
CategoryAxis categoryAxis=plot.getDomainAxis();
catoryAxis.setLableFont(new Font("宋体",Font.bold,22));
categoryAxis.setCategoryLablePositions(CategoryLablePosotions.UP_45);
NumberAxis numberAxis=(NumberAxis)plot.getRangeAxis();
numberAxis.setLableFont(new Font("宋体",Font.bold,22))
return chart;
}
}
}
将struts-plugin-freechart.jar放在lib下面
首先解压缩情切修改struts-plugin-freechart.jar下面的struts-plugin.xml文件增加 extends="struts-default"
然后在打包成jar包:
   进入struts-plugin-freechart文件下面->jar cvf struts-plugin-freechart.jar -C *
struts.xml中的配置:

 
    
        600
        800
    

 

 
 
struts2整合JasperReport报表
下载JasperReport和iReport
执行iReport,双击.exe文件
学会怎样使用iReport
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
阅读(3465) | 评论(0) | 转发(0) |
0

上一篇:Ajax视频学习

下一篇:中科院oracle视频总结

给主人留下些什么吧!~~