转载地址:http://www.blogjava.net/nokiaguy/archive/2009/01/13/251101.html

本系列教程将详细介绍Struts 1.x的基本原理和使用方法,读者可以参阅《Struts 2系列教程》来比较Struts 1.x和Struts 2.x的相同点和不同点。
   在这篇文章中将以一个简单的例子(mystruts)来演示如何使用MyEclipse来开发、运行Struts程序,并给出了解决ActionForm出现乱码问题的方法。读者可以从本文中了解开发Struts 1.x程序的基本过程。

一、本文给出的程序要实现什么功能

mystruts是一个录入和查询产品信息的程序。为了方便起见,本例中的产品信息表只包括了产品ID、产品名称和产品价格三个字段。mystruts的主要功能如下:

1. 接受用户输入的产品ID、产品名称和产品价格。

2. 验证这些字段的合法性。如果某些字段的输入不合法(如未输入产品ID),程序会forward到一个信息显示页,并显示出错原因。

3. 如果用户输入了正确的字段值,程序会将这些字段值保存到数据库中,并显示“保存成功”信息。

4. 用户输入产品名称,并根据产品名称进行模糊查询。如果存在符合要求的产品信息。程序会以表格形式显示这些产品的信息,同时显示记录数。如果未查到任何记录,会显示“没有符合要求的记录!”信息。

二、编写程序前的准备工作

1. 建立数据库


   
在编写程序之前,需要建立一个数据库(struts)和一个表(t_products),建立数据库和表的SQL脚本如下所示:

  # 建立数据库struts
  CREATE DATABASE IF NOT EXISTS struts DEFAULT CHARACTER SET GBK;

# 建立表t_products
  CREATE TABLE IF NOT EXISTS struts.t_products (
    product_id varchar(4) NOT NULL,
    product_name varchar(50) NOT NULL,
    price float NOT NULL,
    PRIMARY KEY  (product_id)
  ) ENGINE=InnoDB DEFAULT CHARSET=gbk;


建立一个支持struts1.xsamples工程

用MyEclipse建立一个samples工程(Web工程),现在这个samples工程还不支持Struts1.x(没有引入相应的Struts jar包、struts-config.xml文件以及其他和Struts相关的配置)。然而,在MyEclipse中这一切并不需要我们手工去加入。而只需要使用MyEclipse的【New Struts Capabilities】对话框就可以自动完成这些工作。

首先选中samples工程,然后在右键菜单中选择【MyEclipse】 > 【New Struts Capabilities】,启动【New Struts Capabilities】对话框。对默认的设置需要进行如下的改动:

(1)将Struts specification改为Struts 1.2。

(2)将Base
package for new classes改为struts。

(3)将Default
application resources改为struts.ApplicationResources。

改完后的【New Struts Capabilities】对话框如图1所示。

图1

在设置完后,点击Finish按钮关闭对话框。在向samples工程添加支持Struts的功能后,主要对samples工程进行了三个操作。

(1)引入了Struts 1.2 的jar包(在samples的工程树中多了一个Struts 1.2 Libraries节点)。

(2)在WEB-INF目录中添加了一个struts-config.xml文件。文件的默认内容如下面的代码所示:

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://struts.apache.org/dtds/struts-config_1_2.dtd">  
  <struts-config>
    <data-sources />
    <form-beans />
    <global-exceptions />
    <global-forwards />
    <action-mappings />
    <message-resources parameter="struts.ApplicationResources" />
  </struts-config>

(3)在WEB-INF中的web.xml文件中添加了处理Struts动作的ActionServlet的配置,代码如下:

<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>3</param-value>
    </init-param>
    <init-param>
      <param-name>detail</param-name>
      <param-value>3</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

    到目前为止,samples工程已经完全支持Struts了。读者可以看到,如果不使用MyEclipse,那么上面所列出的配置文件的内容都必须手工输入。因此,使用MyEclipse来开发Struts程序可以省去很多配置xml文件的工作。

三、实现程序的首页(index.jsp)

    首先在<samples工程目录>中建立一个mystruts目录,然后在<samples工程目录>" mystruts目录中建立一个index.jsp文件,这个文件的内容如下。

  <%@ page pageEncoding="GBK"%>
  <%-- 引用Struts tag--%>
  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  <html>
      <head>
          <title>主界面</title>
      </head>
      <body>
          <table align="center" cellpadding="10" width="100%">
              <tr>
                  <td align="right" width="50%">
                  <%-- 使用Struts tag--%>
                      <html:link forward="newProduct">录入产品信息</html:link>
                  </td>
                  <td>
                      <html:link forward="searchProduct">查询产品信息</html:link>
                  </td>
              </tr>
          </table>
      </body>
  </html>

    在MyEclipse中启动Tomcat(如果Tomcat处于启动状态,在修改完配置文件后,建议在MyEclipse的Servers页重新发布samples工程,以使修改生效)。在IE中输入如下的URL:

http://localhost:8080/samples/mystruts/index.jsp

我们发现在输入上面的URL后,在IE中并未显示正确的运行结果,而是抛出了如下的异常:

java.net.MalformedURLException:
Cannot retrieve ActionForward named newProduct

这个异常表明程序并未找到一个叫newProduct的forward(forward将在后面详细地讲述)。因此,可以断定,在JSP中使用forward时,这个forward必须存在。下面我们来添加index.jsp页面中所使用的两个forward:newProduct和searchProduct。这两个forward分别引向了建立产品信息的页面(newProduct.jsp)和查询产品信息的页面(searchProduct.jsp)。我们可以在struts-config.xml文件中<struts-config>节点中添加两个全局的forward,代码如下:

  <global-forwards>
      <forward name="newProduct" path="/mystruts/newProduct.jsp" />
      <forward name="searchProduct" path="/mystruts/searchProduct.jsp" />
</global-forwards>

上面的代码中所示的newProduct.jsp和searchProduct.jsp目前并不存在(将在以后实现这两个JSP页面),现在重新输入上述的URL,会得到如图2所示的效果。

图2

如果想让index.jsp成为默认的JSP页面,可以在web.xml中的<welcome-file-list>节点中加入如下的内容:

 <welcome-file>index.jsp</welcome-file>

这时在IE中只要输入如下的URL就可以访问index.jsp页面了。

http://localhost:8080/samples/mystruts

四、实现添加和查询产品信息页面

在本节中主要实现了用于输入产品信息(newProduct.jsp)和查询产品信息(searchProduct.jsp)的JSP页面。

在newProduct.jsp页面中有一个form,在form中含有三个文本框,用于分别输入产品ID、产品名称和产品价格。
在<samples工程目录>"mystruts目录中建立一个newProduct.jsp文件,代码如下:

  <%@ page pageEncoding="GBK"%>
  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  <html>
      <head>
          <title>录入产品信息</title>
      </head>
      <body>
          <%-- 向saveProduct动作提交产品信息 --%>
          <html:form action="saveProduct"> 
              <table width="100%">
                  <tr>
                      <td align="center">
                          产品编号:
                          <html:text property="productID" maxlength="4" />
                          <p>
                              产品名称:
                              <html:text property="productName" />
                          <p>
  
                              产品价格:
                              <html:text property="price" />
                      </td>
                  </tr>
                  <tr>
                      <td align="center">
                          <br>
                          <html:submit value=" 保存 " />
                      </td>
                  </tr>
              </table>
          </html:form>
      </body>
  </html>

在searchProduct.jsp页面中有一个form,为了方便起见,在form中只提供了一个文本框用于对产品名称进行模糊查询。在<samples工程目录>" mystruts目录中建立一个searchProduct.jsp文件,代码如下:

  <%@ page pageEncoding="GBK"%>
  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
  <html>
      <head>
          <title>查询产品信息</title>
      </head>
      <body>
          <%--  向searchProduct动作提交查询请求 --%>
          <html:form action="searchProduct">
              <table width="100%">
                  <tr>
                      <td align="center">
                          产品名称:
                          <html:text property="productName" />
                      </td>
                  </tr>
                  <tr>
                      <td align="center">
                          <br>
                          <html:submit value=" 查询 " />
                      </td>
                  </tr>
              </table>
          </html:form>
      </body>
  </html>

现在启动Tomcat,并使用如下两个URL来访问newProduct.jsp和searchProduct.jsp:

http://localhost:8080/samples/mystruts/newProduct.jsp
http://localhost:8080/samples/mystruts/searchProduct.jsp

在IE中输入上面的两个URL后,并不能显示出相应的界面,而会抛出JspException异常,表明未找到saveProduct和searchProduct动作。从这一点可以看出,如果在JSP中使用Struts Action,这些Action必须事先在struts-config.xml文件中定义,否则,JSP程序就无法正常访问。在这两个页面所使用的动作(saveProduct和searchProduct)将会在下面的部分介绍。


五、通过模型类操作数据库

    在这一节我们来编写用于操作数据库的模型类。由于本例子是Web程序,因此,建议在连接数据库时使用数据库连接池。在<Tomcat安装目录>"conf"Catalina"localhost目录中打开samples.xml文件(如果没有该文件,则建立一个samples.xml文件),在<Context>节点中加入如下的内容:

配置连接池(用于连接数据库struts

  <Resource name="jdbc/struts" auth="Container"
                type="javax.sql.DataSource"
                driverClassName="com.mysql.jdbc.Driver"
                url="jdbc:mysql://localhost:3306/struts?characterEncoding=GBK"
                username="root"
                password="1234"              
                maxActive="200"
                maxIdle="50"
                maxWait="3000"/>

本例中提供了两个可以操作数据库的模型类:Product和SearchProduct。其中Product用于验证由客户端提交的产品信息,并向t_products表中写入这些信息。而SearchProduct类用于对t_products表的product_name字段进行模糊查询,并返回查询到的产品信息(包括产品ID、产品名称和产品价格)。

由于Product和SearchProduct都需要使用数据库连接池来连接数据库,因此,可以将连接数据库的工作提出来作为一个父类(Struts类)提供,代码如下:

package util;
import java.sql.Connection;
public class Struts
{
    protected javax.naming.Context ctx = new javax.naming.InitialContext();
    protected javax.sql.DataSource ds;
    protected Connection conn;
    public Struts() throws Exception
    {
        ds = (javax.sql.DataSource) ctx.lookup("java:/comp/env/jdbc/struts");
        conn = ds.getConnection();  // 从数据库连接池获得一个Connection
    }
}

在<samples工程目录>"src目录中建立一个Product.java文件,代码所示:

  package mystruts.model;
  
  import java.sql.*;
  import mystruts.actionform.*;
  
  public class Product extends util.Struts
  {
      private ProductForm form;
  
      public Product(ProductForm form) throws Exception
      {
          super();
          this.form = form;
          validate();
      }
      // 验证客户端提交的数据
      public void validate() throws Exception
      {
          if (form.getProductID().trim().equals(""))
              throw new Exception("产品ID不能为空!");
          if(form.getProductID().length() > 4)
              throw new Exception("产品ID最长为4位!");
          if (form.getProductName().trim().equals(""))
              throw new Exception("产品名称不能为空");
          if (Float.compare(form.getPrice(), 0) <= 0)
              throw new Exception("产品价格必须大于0");
      }
      // 将客户端提交的产品信息保存到t_products中
      public void save() throws Exception
      {
          try
          {
              String productID = form.getProductID();
              String productName = form.getProductName();
              float price = form.getPrice();
              String sql = "INSERT INTO t_products VALUES('" + productID + "',"
                      + "'" + productName + "'," + String.valueOf(price) + ")";
              PreparedStatement pstmt = conn.prepareStatement(sql);
              pstmt.executeUpdate();   // 执行INSERT语句
              pstmt.close();
              conn.close();
          }
          catch (Exception e)
          {
              throw new Exception(e.getMessage());
          }
      }
  }

    在Product类中使用了一个ProductForm类,这个类是一个ActionForm类,它的功能是保存客户端提交的数据。关于这个类将在下面详细介绍。Product类通过构造方法的form参数将客户端提交的数据传入Product类的对象实例中,并在构造方法中验证这些数据,如果发现数据不合法,就会抛出一个异常。当客户端提交的数据合法后,成功建立了一个Product类的对象实例,然后可以通过简单地调用save方法将数据保存到t_products表中。

与Product类似,在<samples工程目录>"src目录中建立一个SearchProduct.java文件,代码如下:

  package mystruts.model;
  
  import java.sql.*;
  import java.util.*;
  import mystruts.actionform.*;
  
  public class SearchProduct extends util.Struts
  {
      private ProductForm form;
  
      public SearchProduct(ProductForm form) throws Exception
      {
          super();
          this.form = form;
      }    
      // 查询产品信息,并通过List返回查询结果
      public List<String[]> search() throws Exception
      {
          List<String[]> result = new LinkedList<String[]>();
          String sql = "SELECT * FROM t_products WHERE product_name like '%" 
+ form.getProductName() + "%'";
          PreparedStatement pstmt =  conn.prepareStatement(sql);
          ResultSet rs = pstmt.executeQuery();  // 开始执行SELECT语句
          while(rs.next())
          {
              String[] row = new String[3];
              row[0] = rs.getString(1);
              row[1] = rs.getString(2);
              row[2] = rs.getString(3);
              result.add(row);
          }
          rs.close();
          conn.close();
          return result;
      }
  }

在SearchProduct类也使用了ProductForm类,但在SearchProduct中并不会验证ProductForm对象实例中的数据,而只是将ProductForm对象作为传递查询请求信息(实际上只需要产品名称)的工具而已。

六、实现控制器

在这一节要实现的控制器是基于Struts的Web程序的核心部分之一:控制器实质上也是普通的Java类,但这个Java类一般要从org.apache.struts.action.Action类
继承。控制器的主要功能是接受并处理从JSP页面提交的数据、通过模型(Model)和数据库交互以及forward到相应的页面(可以是任何页面,如
html、JSP和Servlet等)。在实现控制器之前,需要先实现一个ActionForm类,
这个类的作用是保存JSP页面提交的数据。在<samples工程目录>"src目录中建立一个ProductForm.java文件,代码
如下:

  package mystruts.actionform;
  
  import org.apache.struts.action.*;
  
  public class ProductForm extends ActionForm
  {
      private String productID;  // 产品ID
      private String productName; // 产品名称
      private float price;  // 产品价格
      public String getProductID()
      {
          return productID;
      }
      public void setProductID(String productID)
      {
          this.productID = productID;
      }
      public String getProductName()
      {
          return productName;
      }
      public void setProductName(String productName)
      {
          this.productName = productName;
      }
      public float getPrice()
      {
          return price;
      }
      public void setPrice(float price)
      {
          this.price = price;
      }
  }

从上面的代码可以看出,ActionForm类一般从org.apache.struts.action.ActionForm类继承,而且在类中需要按着需要保存的数据表字段添加属性。如产品ID的属性是productName。在MyEclipse中可以只定义三个private变量,然后使用MyEclipse的【Source】
> 【Generate Getters and Setters...】功能自动产生getter和setter方法。但在给这些属性取名时要注意,private变量的名子和数据表的字段名没有直接的关系,但必须和JSP页面中的<html>标签的property属性值一致,如<html:text property="productName" />表示输入产品名称的文本框,其中property属性的值就是ProductForm类中的productName变量。如果不一致,将会抛出异常。其他和ProductForm类的属性对应的<html>标签可以查看上面的代码。
    光有ActionForm类还不够,还需要在struts-config.xml中的<struts-config>节点中添加如下的内容:

<form-beans>
     <form-bean name="saveProductForm" type=" mystruts.actionform.ProductForm" />
     <form-bean name="searchProductForm" type="mystruts.actionform.ProductForm" />
</form-beans>

上面的代码所配置的两个ActionForm实际上指的是同一个ProductForm类,但这个ProductForm类在后面要讲的两个动作里都要使用,为了更容易理解,为这个ProductForm起了两个不同的别名(saveProductForm和searchProductForm)。
    下面来实现saveProduct动作的代码。Struts Action类必须一般从org.apache.struts.action.Action类继承。一般在Struts
Action类需要覆盖Action类的execute方法。这个方法有每次客户端访问Struts Action时调用。我们可以在方法中处理客户端提交的数据,访问数据库等工作。这个方法返回一个ActionForward类型的值,表明在执行完execute后,要forward到的页面。描述saveProduct动作的类叫SaveProductAction。代码如下:

  package mystruts.action;
  
  import javax.servlet.http.*;
  import org.apache.struts.action.*;
  import mystruts.actionform.*;
  import mystruts.model.*;
  
  public class SaveProductAction extends Action
  {
      // 在客户端访问saveProduct动作时执行该方法
      public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          ProductForm saveProductForm = (ProductForm) form;
          try
          {
              Product product = new Product(saveProductForm);
              product.save();  // 保存产品信息
              request.setAttribute("info", "保存成功!");   
          }
          catch (Exception e)
          {
              request.setAttribute("info", e.getMessage());
          }
          return mapping.findForward("save");
      }
  }

在SaveProductAction类中使用了模型类Product验证并保存产品信息。并将操作结果信息保存在request的属性中,key为“info”。在execute的最后,使用了ActionMapping类的findForward方法在struts-config.xml中寻找一个叫“save”的forward。这个forward是一个JSP页,用于显示是否将产品信息保存成功的信息。为了可以在struts-config.xml中查找这个forward,需要在struts-config.xml的<action-mappings>节点中加入如下的内容。

<action name="saveProductForm" path="/saveProduct"scope="request" type=" mystruts.action.SaveProductAction">
    <forward name="save" path="/mystruts/save.jsp" />
</action>

从上面的代码可以看出,那个用于显示保存状态信息的JSP页面叫save.jsp。在<samples工程目录>"mystruts目录中建立一个save.jsp文件,代码如下:

  <%@ page pageEncoding="GBK"%>
  ${requestScope.info}

在IE中输入如下的URL:

http://localhost:8080/samples/mystruts/newProduct.jsp

在文本框中输入相应的信息后,点“保存”按钮,如果输入的数据是合法的,就会将数据保存在t_products中,
否则会显示出错的原因。   
searchProduct动作的实现和saveProduct差不多,也会为三步:实现动作类(SearchProductAction)、在
struts-config.xml中添加配置信息和实现用于显示查询结果的JSP文件。下面的代码分别显示了这三步所要编写的代码。

SearchProductAction.java

  package mystruts.action;
  
  import javax.servlet.http.*;
  import org.apache.struts.action.*;
  import mystruts.actionform.*;
  import mystruts.model.*;
  import java.util.*;
  
  public class SearchProductAction extends Action
  {
  
      public ActionForward execute(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      {
          ProductForm searchProductForm = (ProductForm) form;
          try
          {
              SearchProduct searchProduct = new SearchProduct(searchProductForm);
              List<String[]> result = searchProduct.search();  // 查询产品信息
              if (result.size() > 0)  // 有符合条件的产品信息
              {
                  request.setAttribute("result", result);
                  request.setAttribute("info", "记录数:" + String.valueOf(result.size()));
              }
              else  // 没有查到任何产品信息
                  request.setAttribute("info", "没有符合要求的记录!");
          }
          catch (Exception e)
          {
              request.setAttribute("info", e.getMessage());
          }
          return mapping.findForward("search");
      }
  }

struts-config.xml中配置searchProduct动作

<action name="searchProductForm" path="/searchProduct" scope="request" type="mystruts.action.SearchProductAction">
    <forward name="search" path="/mystruts/search.jsp" />
</action>

search.jsp

  <%@ page pageEncoding="GBK"%>
  <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
  <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  <html>
      <body>
<%-- 从request的result中取出查询结果 --%>
          <c:set var="result" value="${requestScope.result}" />
          <table width="100%">
              <tr align="center">
                  <td>
                      ${requestScope.info}
                  </td>
              </tr>
              <tr align="center">
                  <td>
                      <logic:present name="result">
                          <table border="1">
                              <tr align="center">
                                  <td> 产品ID </td>
                                  <td> 产品名称 </td>
                                  <td> 价格 </td>
                              </tr>
                              <logic:iterate id="row" name="result">
                                  <tr> <td> ${row[0]} </td>
                                      <td> ${row[1]} </td>
                                      <td> ${row[2]} </td>
                                  </tr>
                              </logic:iterate>
                          </table>
                      </logic:present>
                  </td>
              </tr>
          </table>
      </body>
  </html>



    在IE中输入如下的URL:

http://localhost:8080/samples/%20mystruts/searchProduct.jsp

在“产品名称”文本框中输入产品名称的一部分,程序就会查询出所有包含输入的产品名称的产品信息,并将结果显示出来。

七、解决ActionForm的乱码问题

 

    到现在为止,程序的功能部分已经全部实现完了。但还存在一个问题。当我们在产品名称中输入中文时,虽然将客户端提交的数据成功保存到数据库中,但是在t_products表中的product_name字
段显示的都是乱码。产生这个问题的原因只有一个,就是客户端提交的数据的编码格式和数据库的编码格式不一致造成的。当然,解决这个问题的方法有很多,但笔
者认为最容易的就是使用过滤器。所谓过滤器,就是在客户端提交数据后,在交由服务端处理之前所执行的一段服务端代码(一般为Java代码)。一个过滤器是一个实现javax.servlet.Filter接口的类。在本例中要使用的过滤器类叫EncodingFilter,实现代码如下:

EncodingFilter.java

  package filter;
  import java.io.IOException;
  import javax.servlet.*;
  public class EncodingFilter implements Filter
  {
      public void destroy() {  }
      public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain) throws IOException, ServletException
      {
          request.setCharacterEncoding("GBK");  // 将客户端提交的数据设为GBK编码格式
          // 继续处理客户端提交的数据,如果不写这条语句,Servlet引擎将不会处理所过滤的页面
          chain.doFilter(request, response);      
      }
      public void init(FilterConfig filterConfig) throws ServletException {   }  
  }

Filter接口的doFilter方法是过滤器的核心方法。其中FilterChain类的doFilter方法允许继续处理客户端提交的数据。我们还可以使用这个方法来临时关闭Web站点的某个或全部的页面(根据过滤器的设置而定)。由于本书的数据库使用的是GBK编码格式,因此,需要使用ServletRequest的setCharacterEncoding方法将客户端提交的数据也设为GBK编码格式。

除了实现过滤器类,我们还需要在web.xml中的<web-app>节点加入如下的配置信息才能使过滤器生效:

web.xml中配置过滤器

<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>
        filter.EncodingFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在重新启动Tomcat后,重新输入一条带中文的产品信息,看看是否可以将中文保存在数据库中?

[转]Struts1.x系列教程(1):用MyEclipse开发第一个Struts程序的更多相关文章

  1. MyEclipse开发第一个java程序HelloWorld

    [学习笔记] 用MyEclipse开发第一个java程序: 我们先看看一个具体例子,给你们有个先入为主的感觉. 步骤一:在Eclipse开发工具中我们New一个java项目, 如图2_1 图2_1 步 ...

  2. 使用MyEclipse开发第一个Web程序

    MyEclipse环境配置 首先,安装一个MyEclipse,然后进行一些相关的环境配置(Window->Preferences): 比如字体.Formatter等. 也可以从Eclipse中导 ...

  3. Spring入门教程:通过MyEclipse开发第一个Spring项目

    Animal.java package com.project; public class Animal { private String name; public String getName() ...

  4. webpack4 系列教程(十五):开发模式与webpack-dev-server

    作者按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十五):开发模式与 webpack-dev-server>原文地址.更欢迎来我的 ...

  5. Linux Shell系列教程之(二)第一个Shell脚本

    本文是Linux Shell系列教程的第(二)篇,更多shell教程请看:Linux Shell系列教程 通过上一篇教程的学习,相信大家已经能够对shell建立起一个大体的印象了,接下来,我们通过一个 ...

  6. [Ruby on Rails系列]3、初试Rails:使用Rails开发第一个Web程序

    本系列前两部分已经介绍了如何配置Ruby on Rails开发环境,现在终于进入正题啦! Part1.开发前的准备 本次的主要任务是开发第一个Rails程序.需要特别指出的是,本次我选用了一个(Paa ...

  7. 【转】Struts1.x系列教程(2):简单的数据验证

    转载地址:http://www.blogjava.net/nokiaguy/archive/2009/01/archive/2009/01/13/251197.html 简单验证从本质上说就是在服务端 ...

  8. JXLS 2.4.0系列教程(二)——循环导出一个链表的数据

    请务必先看上一篇文章,本文在上一篇文章的代码基础上修改而成. JXLS 2.4.0系列教程(一)--最简单的模板导出 上一篇文章我们介绍了JXLS和模板导出最简单的应用,现在我们要更进一步,介绍在模板 ...

  9. 【转】Struts1.x系列教程(4):标签库概述与安装

    转载地址:http://www.blogjava.net/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/0 ...

随机推荐

  1. traits的使用

    trait的作用是可以在任何地方使用trait中的方法. trait的定义与定义类相同,定义实例如下: trait tSoneTrait{ //定义一些属性 function someFunction ...

  2. PHP如何关闭notice级别的错误提示

    1.在php.ini文件中改动error_reporting改为:error_reporting=E_ALL & ~E_NOTICE2.如果你不能操作php.ini文件,你可以使用如下方法在你 ...

  3. HTTPS协议简介

    一.HTTPS简介 百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS.本文重点介绍 HTTPS 协议, 并简单介绍部署全站 HTTPS 的意义. HTTPS ...

  4. 一个参数大小写引发的uploadify报错 "Syntax error, unrecognized expression: #"

     上传控件uploadify 报错"Syntax error, unrecognized expression: #" 版本为 uploadify3.2  报错原因:参数ID[hi ...

  5. Spring详细总结

    Spring的特性之一:IOC(控制反转Inverse Of Control),又称依赖注入,是一种重要的面向对象编程的法则来削减计算机程序的耦合问题 也是轻量级spring框架的核心: 依赖注入: ...

  6. mango-1.4.1 文档

    文档目录 快速开始 添加依赖包 数据库准备 创建HelloWorld类 书写插入与查询方法 构造数据源并初始化mango对象 获取dao并调用插入与查询方法 查看完整示例代码和表结构 基本操作 准备工 ...

  7. mysql5.5手册读书日记(3)

    <?php /* MySQL_5.5中文参考手册 587开始 与GROUP BY子句同时使用的函数和修改程序 12.10.1. GROUP BY(聚合)函数 12.10.2. GROUP BY修 ...

  8. LightOj 1220 - Mysterious Bacteria (分解质因子x=b^p 中的 x 求最大的 p)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1220 题意:已知 x=bp 中的 x 求最大的 p,其中 x b p 都为整数 x = ...

  9. What is the difference between parameterized queries and prepared statements?

    Both parameterized queries and prepared statements are exactly the same thing. Prepared statement se ...

  10. usb mass storage

    使用otg端口进行usb slave的测试,需要安装g_file_storage.ko或者g_mass_storage.ko模块. 参考链接 http://blog.csdn.net/freeman1 ...