字符编码的处理和BeanUtils组件的使用

1、字符编码问题解决方案

原理:过滤器技术拦截所有的controll的请求、在controll请求中使用了动态代理的设计模式监听了HttpServletRequest这个接口中getParameter方法的执行、在getParameter执行的时候、我们首先去获取这个数据、再通过判断当前的请求是GET还是POST、如果是GET那么先使用IOS-8859-1进行转码 然后使用UTF-8从新进行编码、如果是POST那么直接使用request.setCharacterEncoding(“UTF-8”)来进行处理

1.1、字符编码处理的实现

      public class CharacterFilter implements Filter{

@Override

public void init(FilterConfig arg0) throws ServletException {

}

    /**

     * 拦截的这个方法

     */

@Override

public void doFilter(ServletRequest request, ServletResponse response,

final FilterChain chain) throws IOException, ServletException {

    

    final HttpServletRequest req=(HttpServletRequest) request;

    final HttpServletResponse resp=(HttpServletResponse) response;

    

    //第一步:将返回数据的编码问题给处理了

    resp.setContentType("text/html;charset=utf-8");

    //POST的解决方案

    req.setCharacterEncoding("UTF-8");

    //第二步:监听httpServletRequest中 getParameter方法的执行

    HttpServletRequest req1= (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),

     new Class[]{HttpServletRequest.class},

     new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

   //监听当前执行的方法是不是 getParameter

   String methodName=method.getName();

   if("getParameter".equals(methodName)){ //说明执行的是getParameter

  //判断当前执行的是POST呢?还是GET呢?

  String reqName=req.getMethod();

  

  //通过key获取这个值

  String val= (String) method.invoke(req, args);

  if("GET".equalsIgnoreCase(reqName)){ //说明是GET方法

  //执行这个方法获取这个值

  val=new String(val.getBytes("ISO-8859-1"),"UTF-8");

  

  }else if("POST".equalsIgnoreCase(reqName)){ //说明是POST方法

  

  }

  //返回这个方法执行的结果

  return val;

   }else{

  return  method.invoke(req, args);

   }

   }

});

 

   //最终要进行放行

   chain.doFilter(req1, resp);

}

@Override

public void destroy() {

}

}
复制代码

2、字符和谐的问题

明白一个问题:什么是字符和谐:类似于博客网站上行 比如你骂人了一句话这句话并不会直接显示出来、而是显示成****等这种现象就称为字符的和谐

2.1、要实现字符和谐首先要解决编码问题(上面已经解决了)

2.2:在过滤器中设置脏数据

    //需要和谐的脏数据

private String[] dirtyData={"MMD","NND","杀人","CTM"};
复制代码

2.3、在处理完字符编码问题的时候进行和谐(在处理完编码之后进行调用)

     protected String handleDirtyData(String val) {

for (int i = 0; i < dirtyData.length; i++) {

if(val.contains(dirtyData[i])){

val=val.replaceAll(dirtyData[i],"***");

}

}

return val;

}
复制代码

3、BeanUtils组件的使用

3.1、Beanutils组件是啥?

 Beanutils不是一个框架、就相当于是一个帮助类、这个帮助类的作用就是专门用来操作我们java Bean

3.2、BeanUtils组件能干啥?

 能够将一个实体的值赋值给另外一个实体、也可以将map类型的值赋值给实体、也可以将实体进行拷贝 

3.3:BeanUtils组件的使用?

3.3.1、导入beanUtils的包

3.3.2、使用BeanUtils组件的API

public void testbeanUtils() throws Exception {

User user=new User(1,"小波波","123");

//使用BeanUtils来操作这个是实体

//API:表示的是给那个对象的那个属性设置什么值

//BeanUtils.setProperty(user,"uName","小波波");

//BeanUtils.copyProperty(user,"uPwd","123");

//API:拷贝一个实体 返回值就是copy生成的新的实体

//User user2=(User) BeanUtils.cloneBean(user);

User user2=new User();

//把一个实体里面的属性copy给另外一个实体的属性

//BeanUtils.copyProperties(user2, user);

//将实体转换成map

//Map<Object,Object> maps=BeanUtils.describe(user);

//获取实体的属性值 并转换成String类型的数组

//String[] strVal=BeanUtils.getArrayProperty(user,"uName");

//将Map中的数据直接赋值给JAVA的对象

Map<String,Object> maps=new HashMap<String, Object>();

maps.put("uId",123);

maps.put("uName","小波波");

maps.put("uPwd","110");

//将map中的数据直接赋值给JAVA对象

BeanUtils.populate(user2, maps);

System.out.println(user2);

}
复制代码

4、Servlet请求参数的自动封装

public static<T> T getObject(HttpServletRequest request,Class clazz) throws Exception{

//反射得到这个数据类型

T t=(T) clazz.newInstance();

//使用beanUtils组件来设置这个值

BeanUtils.populate(t,request.getParameterMap());

return t;

 }
复制代码

5、源数据使用

源数据分类:数据库的源数据 、请求参数的元数据、结果集的元数据  

数据库的元数据:能够获取当前访问数据库的一些信息(数据库的名字、连接的URL、连接的用户名、数据库的版本信息)

请求参数的元数据:能够精确的知道当前的SQL语句中有多少个占位符

结果集元数据:就能清楚的知道当前访问的这个数据库的列名是什么

5.1、数据库的元数据的使用


     public void testDatabaseMetaData() throws Exception {

//第一步:加载驱动

Class.forName("com.mysql.jdbc.Driver");

//第二步:创建连接

Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);

//获取数据库的元数据

DatabaseMetaData data=conn.getMetaData();

//获取数据库的相关信息

System.out.println("数据库的名字:"+data.getDatabaseProductName());

System.out.println("数据库的版本:"+data.getDatabaseProductVersion());

System.out.println("数据库的URL:"+data.getURL());

System.out.println("访问的用户名:"+data.getUserName());

System.out.println("---------------------------------------");

//第三步:创建操作数据库的对象

PreparedStatement state=conn.prepareStatement("select * from msgstateinfo");

//第四步:操作

ResultSet set=state.executeQuery();

//遍历....

while (set.next()) {

String str=set.getString("msgstate");

System.out.println("获取到的数据是:"+str);

}

conn.close();

}
复制代码

5.2、请求参数的元数据

      public void testRequestParameMetaData() throws Exception {

//第一步:加载驱动

Class.forName("com.mysql.jdbc.Driver");

//第二步:创建连接

Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);

System.out.println("---------------------------------------");

//第三步:创建操作数据库的对象

PreparedStatement state=conn.prepareStatement("select * from msgstateinfo where id < ? and msgobj = ? and aa=?");

//第四步:玩下请求参数的元数据

ParameterMetaData data=state.getParameterMetaData();

//现在你就可以知道当前的SQL语句中有多少个占位符了

System.out.println("占位符的个数:"+data.getParameterCount());

conn.close();

}
复制代码

5.3、结果集元数据

    public void testResultSetMetaData() throws Exception {

//第一步:加载驱动

Class.forName("com.mysql.jdbc.Driver");

//第二步:创建连接

Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);

System.out.println("---------------------------------------");

//第三步:创建操作数据库的对象

PreparedStatement state=conn.prepareStatement("select * from t_user");

ResultSet set=state.executeQuery();

//下面就可以获取结果集的元数据了

ResultSetMetaData resultSetMetaData=set.getMetaData();

while (set.next()) {   //相当于是遍历的是行

//我们还可以遍历列

int columnNum=resultSetMetaData.getColumnCount();

//通过列的下标来知道列的名字

for (int i = 0; i < columnNum; i++) {

//通过列的下标来找到列的名字

String columnName=resultSetMetaData.getColumnName(i+1);

//知道了列的名字也就能找到这个列的值了

Object val=set.getObject(columnName);

System.out.println(val);

}

}

conn.close();

} 
复制代码

5.4、封装一个通用的JDBC的增删改的方法

    public void update(String sql, Object... parames) throws Exception {

// 获取连接

Connection conn = getConnection();

// 第二步:获取操作数据库的对象

PreparedStatement state = conn.prepareStatement(sql);

// 第三步:将传递过来的参数直接赋值给占位符

// 获取占位符的个数

ParameterMetaData parameterMetaData = state.getParameterMetaData();

// 获取占位符的个数

int num = parameterMetaData.getParameterCount();

if (parames.length < num) {

throw new RuntimeException("参数不对应没法玩....");

}

// 说明参数是对的

for (int i = 0; i < num; i++) {

// 设置参数了

state.setObject(i + 1, parames[i]);

}

// 执行这个SQL语句

state.executeUpdate();

close();

}
复制代码

5.5、封装一个根据条件查询返回集合的方法


public <T> List<T> findAll(String sql, Class<T> clazz,Object...parames) throws Exception {

//确定返回的这个容器

        List<T> lists=new ArrayList<T>();

// 获取连接

Connection conn = getConnection();

// 第二步:获取操作数据库的对象

PreparedStatement state = conn.prepareStatement(sql);

// 第三步:将传递过来的参数直接赋值给占位符

// 获取占位符的个数

ParameterMetaData parameterMetaData = state.getParameterMetaData();

// 获取占位符的个数

int num = parameterMetaData.getParameterCount();

if (parames.length < num) {

throw new RuntimeException("参数不对应没法玩....");

}

//判断:假设这个SQL语句根本就没有占位符呢?

if(num!=0){   //说明有占位符

// 说明参数是对的

for (int i = 0; i < num; i++) {

// 设置参数了

state.setObject(i + 1, parames[i]);

}

}

// 执行这个SQL语句

ResultSet set=state.executeQuery();

//下面移动游标遍历这个行

//获取这个列的数量

ResultSetMetaData metadata=set.getMetaData();

//可以获取这个列的数量

int columnCount=metadata.getColumnCount();

while (set.next()) {

T t=clazz.newInstance();

//遍历每一个列

for (int i = 0; i <columnCount; i++) {

//获取每一个列的列名

String columnName=metadata.getColumnName(i+1);

//获取这个列的值

Object columnVal= set.getObject(columnName);

//把上面的属性和值 放到这个JAVA对象中去

BeanUtils.copyProperty(t, columnName, columnVal);

}

//将t放到List集合中去

lists.add(t);

}

close();

return lists;

}

``` 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值