struts笔记

Struts视频笔记:

Struts是一个开源的web框架,框架提高了程序的规范的同时也约束了程序员的自由

 

为什么会有struts:

因为我们队mvc理解的不同,可能造成不同公司写程序的时候,规范不统一,这样不利于程序的维护和扩展,所以我们有必要用一个统一的规范来开发项目(struts)

 

Struts 的好处: 程序更加规范化,开发效率提高了,可读性增加了,程序的可维护性增加了

 

运行原理:

一个请求从浏览器发送给web服务器,http://localhost:8080/web应用/action,web服务器首先解析主机à然后解析web应用的名称à在解析出资源名à转发给总司令ActionServlet(该类由struts框架提供给我们的无需编写,只需配置)àActionServlet有一个文件struts-config.xml,该文件配置了表单actionForm(军火库),还配置了action,以及他们之间的对应关系,当ActionServlet拿到命令后它会查询struts-config.xml文件去填充数据,把用户的数据填充到表单里边,à下个动作就是去调用指定的action(小队长),action去从表单中读取数据,à调用某个model(士兵,如service)完成任务,à完成任务把结果返回给ActionServlet总司令(返回一个执行的结果),-->总司令又去查询struts-config.xml文件,决定跳转到哪个jsp页面,à返回一个执行结果(形成静态html文件)à直接返回给web服务器à服务器再把静态页面以http响应给浏览器

 

,登录小项目过程步骤: 新建web工程à导入struts包à编写login.jspà编写actionForm和actionà配置struts-config.xmlà编写ok.jsp和err.jsp à配置web.xml à测试

点击finish,自动创建web.xml和struts-config.xml。

Struts-config.xml中的<action>中的scope指的是actionform的生命周期范围 struts中<action>的scope默认是session

 

配置过滤器 

public class MyFilter extends HttpServlet implements Filter {

           @Override

        public void doFilter(ServletRequest arg0, ServletResponse arg1,

         FilterChain arg2) throws IOException, ServletException {

          arg0.setCharacterEncoding("gb2312");

          arg1.setCharacterEncoding("gb2312");

          arg2.doFilter(arg0, arg1); 

        }

配置web.xml

<filter>

 <filter-name>MyFilter</filter-name>

 <filter-class>com.chao98.services.MyFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>MyFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

上面这次比较浪费资源每次都要去实例化 但是下面这种过滤器不太彻底,往数据库里插入数据时还是会经常出现乱码

public class MyFilter extends HttpServlet implements Filter {

private String encoding;

           public void doFilter(ServletRequest arg0, ServletResponse arg1,

         FilterChain arg2) throws IOException, ServletException {

          // arg0.setCharacterEncoding("gb2312");

           //arg1.setCharacterEncoding("gb2312");

           arg0.setCharacterEncoding(encoding);

          arg2.doFilter(arg0, arg1);

        

        }

 

public void init(FilterConfig arg0) throws ServletException { 

 encoding=arg0.getInitParameter("encoding");

}

然后在web.xml中加入

<init-param>

        <param-name>encoding</param-name>

        <param-value>GB2312</param-value>

 </init-param>

配置struts-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" 

xmlns="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">

<servlet>

   <servlet-name>action</servlet-name>

  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

  <init-param>

      <param-name>config</param-name>

      <param-value>/WEB-INF/struts-config.xml</param-value>

    </init-param>

    <init-param>

      <param-name>debug</param-name>

      <param-value>2</param-value>

    </init-param>

    <init-param>

      <param-name>detail</param-name>

      <param-value>2</param-value>

    </init-param>

    <load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

 <servlet-name>action</servlet-name>

 <url-pattern>*.action</url-pattern>

</servlet-mapping>

写一个关于安全性的过滤器,用于过滤一些用户注册使用的关键字

private String keywords[];

           public void doFilter(ServletRequest arg0, ServletResponse arg1,

         FilterChain arg2) throws IOException, ServletException {

            String username=arg0.getParameter("username");

             System.out.println("this is safe filter !");

             System.out.println(username);

          if(username!=null){

          for(String key:keywords){

          if(key.equals(username)){

          arg0.setAttribute("err", username+"被第二个管理安全的过滤器拦截了");

           arg0.getRequestDispatcher("/WEB-INF/tishi.jsp").forward(arg0, arg1);

           return ;

          }

          }

          }  

          arg2.doFilter(arg0, arg1); 

        } 

public void init(FilterConfig arg0) throws ServletException { 

     keywords=arg0.getInitParameter("keywords").split(";");

 } 

然后在web.xml配置过滤器还有设置要过滤的关键字

        <init-param>

        <param-name>keywords</param-name>

     <param-value>xiaomao;xiaoxiao</param-value>

 </init-param>

    

 

每个action是单态的,包括actionserver,对网站并发性有影响 若要证明的话在***action.java中声明一个静态变量,每次访问自加

什么是单态: 单态是指在整个运行过程中,始终是一个对象;

struts-config.xml默认放在WEB-INF目录下,也可以放到其他地方,只需要在web.xml中的

<init-param>

      <param-name>config</param-name>

      <param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

有多个struts-config.xml只需用","号隔开

 java 中插入数据库的语句需要注意标点 st.executeUpdate("insert into user(username,password) values("+"'"+u.getUsername()+"'"+","+"'"+u.getPassword()+"'"+")");

jstl(jsp startand tag liblary) jsp标准标签库: 可以提高开发速度,代码简洁

升级jsp  页面 <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">替换8.5myeclipse:

D:\Program\Files\Myeclipse\Common\plugins\com.genuitec.eclipse.wizards_8.5.0.me201003052220.jar\templates\jsp\jsp.vtl的

6.5myeclipse:D:\ProgramFiles\MyEclipse6.5\myeclipse\eclipse\plugins\com.genuitec.eclipse.wizards_6.5.0.zmyeclipse650200806\templates\jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 这样比较符合现在的开发潮流

各个jstl标签

<c:out>:

<c:out value="hello world"></c:out>

<c:out value="${username}" default="没有值" escapeXml="false" ></c:out>等同于request.getAttribute("user").toString();

escapeXml表示是否安装html样式显示 默认是true:表示以文本显示

 如何输出request,session,application, pageContext域对象的数据

    <%

    request.setAttribute("hello","request你好!");

    session.setAttribute("hello","session你好!");

    application.setAttribute("hello","application你好");

    pageContext.setAttribute("hello","pageContext你们<a href='http://www.baidu.com'>百度</a>");

      %>

     这里有个优先级的问题,pageContext>request>session>application

<c:out value="${hello}" default="没有值" escapeXml="false" >

     如果是在同一个页面,那么这段代码输出pageContext你们好百度 

  <%

  User u=new User();

  u.setUsername("admin");

  u.setPassword("admin");

  request.setAttribute("user",u);

   %>

   <c:out value="${user.username}"></c:out> |  |<c:out value="${user.password}"></c:out>

   相当于(User) request.setAttribute("user").getUsername();

<c:set>:

 <c:set var="abc"  value="中国,北京" scope="request"></c:set>

 <c:out value="${abc}"/>

<c:remove var="abc"/> 移除 之后 中国北京将不再显示

<c:catch>:

<c:catch var="err">

      <%int i=3/0; %>

    </c:catch>

<c:out value="${err.message}"></c:out>

  <c:if test="${2<30?true:false}">ok</c:if> 

<c:if>:

   <%

  request.setAttribute("a","hello");

  request.setAttribute("age","22"); %>

  判断字符串:  

   <c:if test="${a=='hello'}">

   hello

   </c:if> 

  判断数值

  <c:if test="${age>12  and age<30 or age==22}">

  年龄大于12 小于30 ${age }

  </c:if> <%

 ArrayList<User> al=new ArrayList<User>();

 User u1=new User();

 u1.setUsername("陈超");

 u1.setPassword("tiger");

  User u2=new User();

 u2.setUsername("system");

 u2.setPassword("manager");

  al.add(u1);  al.add(u2);

request.setAttribute("alluser",al);

  %>

 <c:forEach items="${alluser}" var="u">

    ${u.username}  

     ${u.password} <br/> 

</c:forEach> 

第一种迭代  

<c:forEach var="i" begin="1" end="10">${i}  </c:forEach>

 <br/>

第二种迭代

<c:forEach var="i" begin="1" end="10" step="3">${i}  </c:forEach><br />

用于分隔字符:<c:forTokens items="11;33;44;52;" delims=";" var="temp">${temp}</c:forTokens>

什么时候用$,什么时候不用$

如果是从某个域对象中取出值,取的是一个变量就要用$ ,取的是一个固定的值就不要$

第一种:Window.open(); 这种方式比较慢

第二种:window.location.href=”/web应用名/goManager?pageNow=”+pageNow

<c:if test="${pageNow>1}">前一页:<a href=/web应用名/goManager?pageNow=${pageNow-1}></c:if> 

当前页:<c:forEach><a href="/web应用名/gotoManage?pageNow=${i}">[${i }]</a></c:forEach>

<c:if test="${pageNow<pageCount}">后一页:<a href=”/web应用名/goManager?pageNow=${pageNow+1}”>

</c:if>

当前页${pageNow } /总页数 ${pageCount } 跳转到<input type="button" id="pageNow" name="pageNow" value=""/>

<%

      Map map=new HashMap();

      //map.put("aa","admin");

    //  map.put("bb","scott");

      User u1=new User();

      u1.setUsername("xiaoming");

      u1.setPassword("xiaoming");

       User u2=new User();

      u2.setUsername("xiaoming");

      u2.setPassword("xiaoming");

      map.put("u1",u1);

      map.put("u2",u2); 

      request.setAttribute("person",map); 

      %>

      <c:forEach items="${person}" var="per">

      key:${per.key }值 name: ${per.value.username }值 password:${per.value.password }<br/>

      </c:forEach>

    <%

    Set set=new HashSet();

    User u3=new User();

    u3.setUsername("scott");

    u3.setPassword("tiger"); 

    set.add(u3);

    request.setAttribute("setuser" ,set); 

     %>

  <c:forEach items="${setuser}" var="myusers">

      值 name: ${myusers.username }值 password:${myusers.password }<br/> 

    <c:if test="${!empty setuser}">有人</c:if></c:forEach>

    重定向:<c:redirect url="http://www.hao123.cn"/> 

import标签:

    <c:import url="a.jsp">

    <c:param name="name" value="admin"/>

    </c:import> 

Strtus标签:

<html:base ref="http://www.baidu.com"/><a href="#">goto</a>

如果没有给超链接设置则默认跳到百度(如上)

<html:image src="images/chadu.png"></html:image>这是一个图片按钮

<html:img src="images/chadu.png"/>这是真真正正的一i张图片

bean标签: 用于输出信息 

<%

User u1=new User();

u1.setUsername("admin");

u1.setPassword("admin");

request.setAttribute("user",u1); 

 %>

  <bean:write name="user" property="username"></bean:write>

 另外还有两种创建bean的方法,但是用的不多

  <bean:define id=""/></bean:define>

  <jsp:useBean id="u2" class="com.chao98.forms.User"></jsp:useBean>

 <jsp:setProperty name="u2" property="username" value="chenchao"/>  

Logic 标签:  

 

logic标签使用

  <%

  User u1=new User();

  u1.setUsername("admin");

  u1.setPassword("aa"); 

  User u2=new User();

  u2.setUsername("tiger");

  u2.setPassword("ac"); 

  User u3=new User();

  u3.setUsername("scott");

  u3.setPassword("ab");

  ArrayList<User> al=new ArrayList<User>();

  al.add(u1);

  al.add(u2);

  al.add(u3);

  request.setAttribute("users",al);

   %>

   <logic:iterate id="user" name="users">

      <bean:write name="user" property="username"/>

       <bean:write name="user" property="password"/><br/>

   </logic:iterate>

  <logic:empty name="ee">

      属性不存在

   </logic:empty>

<logic:notEmpty name="users">

      users属性存在

   </logic:notEmpty>

   <logic:iterate id="myusers" name="users">

   <logic:greaterThan value="20" property="age" name="myusers">

      年龄大于二十

   </logic:greaterThan>

   </logic:iterate>

 

标签的选择通常会选择el表达式$

op    Struts 第23讲: 开发struts 的用户管理系统

Create  table users (

 Id  int  primary key,

Name  varchar(20) not null,

Pwd varchar(30) not null,

Email varchar(30) not null,

Tel varchar(30) not null,

Grade int default 1 not null

)

如果中文不能加入的话 show variables like ‘%char%’;

Set character_set_client=gbk

注销退出登录 

  request.getSession().invalidate(); //会把所有的session都删除

 return mapping.findForward("logout");

动态表单(dynimic form):  当我们表单个数和类型不确定的情况下,我们就可以使用动动态表单来解决
动态表单和普通表单的区别: 

1普通表单actionForm 是首先你需要定义这样一个类,然后配置到struts-config中,

2,动态表单完全依赖反射机制创建,所以不要去定义表单类,直接在struts-config.xml中配置即可

<form-bean name=”userForm”

type=”org.apache.struts.action.DynaActionForm”>

<form-property name=”username” type=”java.lang.String/>

</form-bean>

文件的上传与下载

读取文件(inputStream) 写文件(outputStream);

 案例项目:

1:

 <form enctype="multipart/form-data" action="${pageContext.request.contextPath}/register.do" method="post">

   name:<input type="text" name="username"/><br/>

   photo:<input type="file"  name="myphoto"/><br/>

   <input type="submit" value="regist" />

  </form>

2:

public class UserForm extends ActionForm {  

private String username;

private FormFile myphoto;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public FormFile getMyphoto() {

return myphoto;

}

public void setMyphoto(FormFile myphoto) {

this.myphoto = myphoto;

3:

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response) {

   UserForm userForm=(UserForm)form;

   String username=userForm.getUsername();//取出用户名字

   FormFile formFile=userForm.getMyphoto(); 

   // 通过FormFile 我们可以获取关于上次文件的各种信息

    String fileName=formFile.getFileName();

    int fileSize=formFile.getFileSize();

    System.out.println("文件名称:"+fileName);

    System.out.println("文件大小:"+fileSize);

    InputStream is=null;

    OutputStream os=null;

    try {//取出输入流

  is=formFile.getInputStream();

  //得到输出流--文件

  // 1 得到file文件夹上传到tomcat服务器后的绝对路径

 String  keepFilePath=this.getServlet().getServletContext().getRealPath("file");

  System.out.println(keepFilePath);//打印路径

  os=new FileOutputStream(keepFilePath+"\\"+fileName);//读取文件并写出到服务器file

  int len=0;//缓存

  byte []bytes=new byte[1024];

  //循环处理

  while((len=is.read(bytes))>0){

  os.write(bytes,0,len);//读一点写一点

  }

} catch (FileNotFoundException e) { 

e.printStackTrace();

} catch (IOException e) { 

e.printStackTrace();

}finally{

try {

is.close();  

} catch (IOException e) { 

e.printStackTrace();

}

}

return null;

}

4: 在webroot下建立一个file文件夹

完善struts文件上传(上面这种如果上传文件名相同的文件的话就会被覆盖

首先了解uuid 的简单使用方法: 

 String uuids=(java.util.UUID.randomUUID()).toString();

面试题subString(int beginindex,int endindex);是如何截取的 : 获取字符串的一个子串,从beginindex包扩beginindex  取到endindex ,但是不包括endindex 如

 String subString="helloworld!";

 System.out.println(subString.substring(0,5)); 

//打出hello beginindex是从0开始的 

优化后的代码为

public class RegisterAction extends Action { 

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response) {

   UserForm userForm=(UserForm)form;

   String username=userForm.getUsername();//取出用户名字

   FormFile formFile=userForm.getMyphoto(); 

   // 通过FormFile 我们可以获取关于上次文件的各种信息

    String fileName=formFile.getFileName();

    String newFileName="";

    int beginIndex=fileName.lastIndexOf("."); 

    String uuid=(java.util.UUID.randomUUID()).toString();

    newFileName=uuid+fileName.substring(beginIndex,  fileName.length());

    int fileSize=formFile.getFileSize(); 

    System.out.println("uuid:"+uuid);

    System.out.println("文件名称:"+fileName);

    System.out.println("新文件名称:"+newFileName);

    System.out.println("文件大小:"+fileSize); 

    InputStream is=null;

    OutputStream os=null; 

    try {//取出输入流

  is=formFile.getInputStream();

  //得到输出流--文件

  // 1 得到file文件夹上传到tomcat服务器后的绝对路径

  String  keepFilePath=this.getServlet().getServletContext().getRealPath("file");

  System.out.println(keepFilePath);//打印路径

  os=new FileOutputStream(keepFilePath+"\\"+newFileName);//读取文件并写出到服务器file

  int len=0;//缓存

  byte []bytes=new byte[1024];

  //循环处理

  while((len=is.read(bytes))>0){

  os.write(bytes,0,len);//读一点写一点

       return mapping.findForward("loginok");

 

  }

} catch (FileNotFoundException e) { 

e.printStackTrace();

} catch (IOException e) { 

e.printStackTrace();

}finally{

try {

is.close();  

} catch (IOException e) { 

e.printStackTrace();

}

}

return mapping.findForward("loginerr");

}

}

注意事项:如果文件名是中文怎么办?

做一个过滤器

    arg0.setCharacterEncoding("UTF-8");

 arg1.setCharacterEncoding("UTF-8");

 arg2.doFilter(arg0, arg1);

案例: 保存到数据库中

Create database userdb2;

Use userdb2;

Create table t_users 

(username varchar(30) unique not null,

myphoto varchar(128) not null,##保存新的文件名

myphoto2 varchar(128) not null ##保存旧的文件名

);

Q:1272307737

 

文件下载

如果下载的文件时中文名那么我们需要在action中对其进行处理

String filterFilkename=java.net.URLEncoder.encode(u.getMyphoto(),"GB2312");

思考: 如何控制文件的大小?

如何控制文件上传类型?

可以从D:\Program Files\Tomcat 6.0\conf目录下的 web.xml中可以查看文件的类型

如何防止用户名重复?

 

posted @ 2014-10-31 16:00  洒洒  阅读(258)  评论(0编辑  收藏  举报