五、通过模型类操作数据库
在这一节我们来编写用于操作数据库的模型类。由于本例子是 Web 程序,因此,建议在连接数据库时使用数据库连接池。在 <Tomcat 安装目录 >"conf"Catalina"localhost 目录中打开 samples.xml 文件(如果没有该文件,则建立一个 samples.xml 文件),在 <Context> 节点中加入如下的内容:
在 <samples 工程目录 >"src 目录中建立一个 Product.java 文件,代码所示:
在 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文件,代码如下:
上面的代码所配置的两个 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 。代码如下:
在 SaveProductAction 类中使用了模型类 Product 验证并保存产品信息。并将操作结果信息保存在 request 的属性中, key 为“ info ”。在 execute 的最后,使用了 ActionMapping 类的 findForward 方法在 struts-config.xml 中寻找一个叫“ save ”的 forward 。这个 forward 是一个 JSP 页,用于显示是否将产品信息保存成功的信息。为了可以在 struts-config.xml 中查找这个 forward ,需要在 struts-config.xml 的 <action-mappings> 节点中加入如下的内容。
从上面的代码可以看出,那个用于显示保存状态信息的 JSP 页面叫 save.jsp 。在 <samples 工程目录 >"mystruts 目录中建立一个 save.jsp 文件,代码如下:
在这一节我们来编写用于操作数据库的模型类。由于本例子是 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" />
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
}
}
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());
}
}
}
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;
}
}
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;
}
}
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> 节点中添加如下的内容:
光有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 >
< 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 " );
}
}
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 >
< forward name ="save" path ="/mystruts/save.jsp" />
</ action >
从上面的代码可以看出,那个用于显示保存状态信息的 JSP 页面叫 save.jsp 。在 <samples 工程目录 >"mystruts 目录中建立一个 save.jsp 文件,代码如下:
<
%@ page
pageEncoding
="GBK"
%
>
${requestScope.info}
${requestScope.info}
在IE
中输入如下的URL
:
http://localhost:8080/samples/mystruts/newProduct.jsp
在文本框中输入相应的信息后,点“保存”按钮,如果输入的数据是合法的,就会将数据保存在t_products 中,否则会显示出错的原因。 searchProduct动作的实现和saveProduct差不多,也会为三步:实现动作类(SearchProductAction)、在struts-config.xml中添加配置信息和实现用于显示查询结果的JSP文件。下面的代码分别显示了这三步所要编写的代码。
SearchProductAction.java
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 " );
}
}
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 >
< 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 >
<% @ 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
在“产品名称”文本框中输入产品名称的一部分,程序就会查询出所有包含输入的产品名称的产品信息,并将结果显示出来。
http://localhost:8080/samples/%20mystruts/searchProduct.jsp
在“产品名称”文本框中输入产品名称的一部分,程序就会查询出所有包含输入的产品名称的产品信息,并将结果显示出来。
七、解决
ActionForm
的乱码问题
到现在为止,程序的功能部分已经全部实现完了。但还存在一个问题。当我们在产品名称中输入中文时,虽然将客户端提交的数据成功保存到数据库中,但是在t_products
表中的product_name
字段显示的都是乱码。产生这个问题的原因只有一个,就是客户端提交的数据的编码格式和数据库的编码格式不一致造成的。当然,解决这个问题的方法有很多,但笔者认为最容易的就是使用过滤器。所谓过滤器,就是在客户端提交数据后,在交由服务端处理之前所执行的一段服务端代码(一般为Java
代码)。一个过滤器是一个实现javax.servlet.Filter
接口的类。在本例中要使用的过滤器类叫EncodingFilter
,实现代码如下:
EncodingFilter.java
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 { }
}
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 >
< 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后,重新输入一条带中文的产品信息,看看是否可以将中文保存在数据库中?
本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/215248,如需转载请自行联系原作者