zoukankan      html  css  js  c++  java
  • 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:ProgramFilesMyeclipseCommonpluginscom.genuitec.eclipse.wizards_8.5.0.me201003052220.jar emplatesjspjsp.vtl的

    6.5myeclipse:D:ProgramFilesMyEclipse6.5myeclipseeclipsepluginscom.genuitec.eclipse.wizards_6.5.0.zmyeclipse650200806 emplatesjsp

    <!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 FilesTomcat 6.0conf目录下的 web.xml中可以查看文件的类型

    如何防止用户名重复?

     

  • 相关阅读:
    Git一些简单但非常重要并常用的操作命令
    利用fastjson解析json并通过js&ajax实现页面的无跳转刷新
    利用Graphviz绘制逻辑关系依赖图
    oracle导入.dmp文件
    Linux查找当前目录5天的文件并打包
    Web安全相关(三):开放重定向(Open Redirection)
    Web安全相关(二):跨站请求伪造(CSRF/XSRF)
    Web安全相关(一):跨站脚本攻击(XSS)
    密码学应用(DES,AES, MD5, SHA1, RSA, Salt, Pkcs8)
    行为驱动开发(BDD)实践示例
  • 原文地址:https://www.cnblogs.com/thinksasa/p/4065287.html
Copyright © 2011-2022 走看看