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

╰半夏微凉° 2024-05-23 22:10 128阅读 0赞

format_png

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

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

1.1、字符编码处理的实现

  1. public class CharacterFilter implements Filter{
  2. @Override
  3. public void init(FilterConfig arg0) throws ServletException {
  4. }
  5. /**
  6. * 拦截的这个方法
  7. */
  8. @Override
  9. public void doFilter(ServletRequest request, ServletResponse response,
  10. final FilterChain chain) throws IOException, ServletException {
  11. final HttpServletRequest req=(HttpServletRequest) request;
  12. final HttpServletResponse resp=(HttpServletResponse) response;
  13. //第一步:将返回数据的编码问题给处理了
  14. resp.setContentType("text/html;charset=utf-8");
  15. //POST的解决方案
  16. req.setCharacterEncoding("UTF-8");
  17. //第二步:监听httpServletRequest中 getParameter方法的执行
  18. HttpServletRequest req1= (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),
  19. new Class[]{HttpServletRequest.class},
  20. new InvocationHandler() {
  21. @Override
  22. public Object invoke(Object proxy, Method method, Object[] args)
  23. throws Throwable {
  24. //监听当前执行的方法是不是 getParameter
  25. String methodName=method.getName();
  26. if("getParameter".equals(methodName)){ //说明执行的是getParameter
  27. //判断当前执行的是POST呢?还是GET呢?
  28. String reqName=req.getMethod();
  29. //通过key获取这个值
  30. String val= (String) method.invoke(req, args);
  31. if("GET".equalsIgnoreCase(reqName)){ //说明是GET方法
  32. //执行这个方法获取这个值
  33. val=new String(val.getBytes("ISO-8859-1"),"UTF-8");
  34. }else if("POST".equalsIgnoreCase(reqName)){ //说明是POST方法
  35. }
  36. //返回这个方法执行的结果
  37. return val;
  38. }else{
  39. return method.invoke(req, args);
  40. }
  41. }
  42. });
  43. //最终要进行放行
  44. chain.doFilter(req1, resp);
  45. }
  46. @Override
  47. public void destroy() {
  48. }
  49. }
  50. 复制代码

2、字符和谐的问题

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

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

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

  1. //需要和谐的脏数据
  2. private String[] dirtyData={"MMD","NND","杀人","CTM"};
  3. 复制代码

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

  1. protected String handleDirtyData(String val) {
  2. for (int i = 0; i < dirtyData.length; i++) {
  3. if(val.contains(dirtyData[i])){
  4. val=val.replaceAll(dirtyData[i],"***");
  5. }
  6. }
  7. return val;
  8. }
  9. 复制代码

3、BeanUtils组件的使用

3.1、Beanutils组件是啥?

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

3.2、BeanUtils组件能干啥?

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

3.3:BeanUtils组件的使用?

3.3.1、导入beanUtils的包

3.3.2、使用BeanUtils组件的API

  1. public void testbeanUtils() throws Exception {
  2. User user=new User(1,"小波波","123");
  3. //使用BeanUtils来操作这个是实体
  4. //API:表示的是给那个对象的那个属性设置什么值
  5. //BeanUtils.setProperty(user,"uName","小波波");
  6. //BeanUtils.copyProperty(user,"uPwd","123");
  7. //API:拷贝一个实体 返回值就是copy生成的新的实体
  8. //User user2=(User) BeanUtils.cloneBean(user);
  9. User user2=new User();
  10. //把一个实体里面的属性copy给另外一个实体的属性
  11. //BeanUtils.copyProperties(user2, user);
  12. //将实体转换成map
  13. //Map<Object,Object> maps=BeanUtils.describe(user);
  14. //获取实体的属性值 并转换成String类型的数组
  15. //String[] strVal=BeanUtils.getArrayProperty(user,"uName");
  16. //将Map中的数据直接赋值给JAVA的对象
  17. Map<String,Object> maps=new HashMap<String, Object>();
  18. maps.put("uId",123);
  19. maps.put("uName","小波波");
  20. maps.put("uPwd","110");
  21. //将map中的数据直接赋值给JAVA对象
  22. BeanUtils.populate(user2, maps);
  23. System.out.println(user2);
  24. }
  25. 复制代码

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

  1. public static<T> T getObject(HttpServletRequest request,Class clazz) throws Exception{
  2. //反射得到这个数据类型
  3. T t=(T) clazz.newInstance();
  4. //使用beanUtils组件来设置这个值
  5. BeanUtils.populate(t,request.getParameterMap());
  6. return t;
  7. }
  8. 复制代码

5、源数据使用

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

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

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

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

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

  1. public void testDatabaseMetaData() throws Exception {
  2. //第一步:加载驱动
  3. Class.forName("com.mysql.jdbc.Driver");
  4. //第二步:创建连接
  5. Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);
  6. //获取数据库的元数据
  7. DatabaseMetaData data=conn.getMetaData();
  8. //获取数据库的相关信息
  9. System.out.println("数据库的名字:"+data.getDatabaseProductName());
  10. System.out.println("数据库的版本:"+data.getDatabaseProductVersion());
  11. System.out.println("数据库的URL:"+data.getURL());
  12. System.out.println("访问的用户名:"+data.getUserName());
  13. System.out.println("---------------------------------------");
  14. //第三步:创建操作数据库的对象
  15. PreparedStatement state=conn.prepareStatement("select * from msgstateinfo");
  16. //第四步:操作
  17. ResultSet set=state.executeQuery();
  18. //遍历....
  19. while (set.next()) {
  20. String str=set.getString("msgstate");
  21. System.out.println("获取到的数据是:"+str);
  22. }
  23. conn.close();
  24. }
  25. 复制代码

5.2、请求参数的元数据

  1. public void testRequestParameMetaData() throws Exception {
  2. //第一步:加载驱动
  3. Class.forName("com.mysql.jdbc.Driver");
  4. //第二步:创建连接
  5. Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);
  6. System.out.println("---------------------------------------");
  7. //第三步:创建操作数据库的对象
  8. PreparedStatement state=conn.prepareStatement("select * from msgstateinfo where id < ? and msgobj = ? and aa=?");
  9. //第四步:玩下请求参数的元数据
  10. ParameterMetaData data=state.getParameterMetaData();
  11. //现在你就可以知道当前的SQL语句中有多少个占位符了
  12. System.out.println("占位符的个数:"+data.getParameterCount());
  13. conn.close();
  14. }
  15. 复制代码

5.3、结果集元数据

  1. public void testResultSetMetaData() throws Exception {
  2. //第一步:加载驱动
  3. Class.forName("com.mysql.jdbc.Driver");
  4. //第二步:创建连接
  5. Connection conn= DriverManager.getConnection(URL, USER, PASSWORD);
  6. System.out.println("---------------------------------------");
  7. //第三步:创建操作数据库的对象
  8. PreparedStatement state=conn.prepareStatement("select * from t_user");
  9. ResultSet set=state.executeQuery();
  10. //下面就可以获取结果集的元数据了
  11. ResultSetMetaData resultSetMetaData=set.getMetaData();
  12. while (set.next()) { //相当于是遍历的是行
  13. //我们还可以遍历列
  14. int columnNum=resultSetMetaData.getColumnCount();
  15. //通过列的下标来知道列的名字
  16. for (int i = 0; i < columnNum; i++) {
  17. //通过列的下标来找到列的名字
  18. String columnName=resultSetMetaData.getColumnName(i+1);
  19. //知道了列的名字也就能找到这个列的值了
  20. Object val=set.getObject(columnName);
  21. System.out.println(val);
  22. }
  23. }
  24. conn.close();
  25. }
  26. 复制代码

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

  1. public void update(String sql, Object... parames) throws Exception {
  2. // 获取连接
  3. Connection conn = getConnection();
  4. // 第二步:获取操作数据库的对象
  5. PreparedStatement state = conn.prepareStatement(sql);
  6. // 第三步:将传递过来的参数直接赋值给占位符
  7. // 获取占位符的个数
  8. ParameterMetaData parameterMetaData = state.getParameterMetaData();
  9. // 获取占位符的个数
  10. int num = parameterMetaData.getParameterCount();
  11. if (parames.length < num) {
  12. throw new RuntimeException("参数不对应没法玩....");
  13. }
  14. // 说明参数是对的
  15. for (int i = 0; i < num; i++) {
  16. // 设置参数了
  17. state.setObject(i + 1, parames[i]);
  18. }
  19. // 执行这个SQL语句
  20. state.executeUpdate();
  21. close();
  22. }
  23. 复制代码

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

  1. public <T> List<T> findAll(String sql, Class<T> clazz,Object...parames) throws Exception {
  2. //确定返回的这个容器
  3. List<T> lists=new ArrayList<T>();
  4. // 获取连接
  5. Connection conn = getConnection();
  6. // 第二步:获取操作数据库的对象
  7. PreparedStatement state = conn.prepareStatement(sql);
  8. // 第三步:将传递过来的参数直接赋值给占位符
  9. // 获取占位符的个数
  10. ParameterMetaData parameterMetaData = state.getParameterMetaData();
  11. // 获取占位符的个数
  12. int num = parameterMetaData.getParameterCount();
  13. if (parames.length < num) {
  14. throw new RuntimeException("参数不对应没法玩....");
  15. }
  16. //判断:假设这个SQL语句根本就没有占位符呢?
  17. if(num!=0){ //说明有占位符
  18. // 说明参数是对的
  19. for (int i = 0; i < num; i++) {
  20. // 设置参数了
  21. state.setObject(i + 1, parames[i]);
  22. }
  23. }
  24. // 执行这个SQL语句
  25. ResultSet set=state.executeQuery();
  26. //下面移动游标遍历这个行
  27. //获取这个列的数量
  28. ResultSetMetaData metadata=set.getMetaData();
  29. //可以获取这个列的数量
  30. int columnCount=metadata.getColumnCount();
  31. while (set.next()) {
  32. T t=clazz.newInstance();
  33. //遍历每一个列
  34. for (int i = 0; i <columnCount; i++) {
  35. //获取每一个列的列名
  36. String columnName=metadata.getColumnName(i+1);
  37. //获取这个列的值
  38. Object columnVal= set.getObject(columnName);
  39. //把上面的属性和值 放到这个JAVA对象中去
  40. BeanUtils.copyProperty(t, columnName, columnVal);
  41. }
  42. //将t放到List集合中去
  43. lists.add(t);
  44. }
  45. close();
  46. return lists;
  47. }
  48. ```

发表评论

表情:
评论列表 (有 0 条评论,128人围观)

还没有评论,来说两句吧...

相关阅读