作业B之任务一
1. 使用反射机制实现jdbc查询结果集到实体类的转化
- 这个主要是用的使反射的机制,把原来的类的字节码文件结构重组,重新使用。
- package com.dys.JDBC;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
public class Jdbc {
private <Type> List<Type> setMetaData(ResultSet rs, Class<Type> clazz) throws Exception {
List<Type> tList = new ArrayList<Type>();
Type t = null;
while (rs.next()) {
t = clazz.newInstance();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
for (int i = 1; i <= count; i++) {
String name = rsmd.getColumnName(i);
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
field.set(t, rs.getObject(name));
}
tList.add(t);
}
return tList;
}
}
2. 使用反射实现json的生成和解码即:实体类和json的互转,json可用string代替(选做:支持类属性为其他对象,list等特殊结构,支持list等集合结构转换)
- 在这里面json和类相互转换的时候,引来一些其他的jar包(使用了JSONarray等工具类);其次要注意json类的对象和类的对象一定要注意json的语法结构,选做list的时候要注意list就是多个json对象的集合,想办法解析成一个一个对象就好了。
package com.dys.Json;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JSONUtils {
public static String ObjToJson(Object obj) {
String json = "";
if (obj != null) {
StringBuffer sb = new StringBuffer();
if (obj instanceof List) {
sb.append("[");
List<?> list = (List<?>) obj;
for (int i = 0; i < list.size(); i++) {
parseObjToJson(sb, list.get(i), true);
if (i < list.size() - 1) {
sb.append(",");
}
}
} else {
parseObjToJson(sb, obj, false);
}
json = sb.toString();
}
return json;
}
private static void parseObjToJson(StringBuffer sb, Object obj, boolean isFromList) {
if (sb != null && obj != null) {
if (!isFromList) {
sb.append("{");
}
List<Field> fields = new ArrayList<>();
getAllFields(obj.getClass(), fields);
if (!fields.isEmpty()) {
for (int i = 0; i < fields.size(); i++) {
Field field = fields.get(i);
Object fieldValue = null;
String fieldName = field.getName();
try {
fieldValue = field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (fieldValue != null) {
sb.append("\"");
sb.append(fieldName);
sb.append("\":");
if (fieldValue instanceof Integer
|| fieldValue instanceof Double ||
fieldValue instanceof Long ||
fieldValue instanceof Boolean) {
sb.append(fieldValue.toString());
} else if (fieldValue instanceof String || fieldValue instanceof UUID || fieldValue
instanceof Enum) {
sb.append("\"");
sb.append(fieldValue.toString());
sb.append("\"");
} else if (fieldValue instanceof List) {
parseListToJson(sb, fieldValue);
} else {
parseObjToJson(sb, fieldValue, false);
}
if (i != (fields.size() - 1)) {//排除最后一个字段加逗号
sb.append(",");
}
}
}
} else {
if (obj instanceof Integer || obj instanceof Double || obj instanceof Long ||
obj instanceof Boolean) {
sb.append(obj.toString());
} else if (obj instanceof String || obj instanceof UUID) {
sb.append("\"");
sb.append(obj.toString());
sb.append("\"");
}
}
if (!isFromList) {
sb.append("}");
}
}
}
private static void parseListToJson(StringBuffer sb, Object fieldValue) {
if (sb != null && fieldValue != null) {
List list = (List) fieldValue;
sb.append("[");
for (int i = 0; i < list.size(); i++) {
parseObjToJson(sb, list.get(i), true);
if (i != (list.size() - 1)) {
sb.append(",");
}
}
sb.append("]");
}
}
private static void getAllFields(Class<?> clazz, List<Field> fields) {
if (clazz == null) {
return;
}
if (fields == null) {
fields = new ArrayList<>();
}
Field[] declaredFields = clazz.getFields();
for (Field field : declaredFields) {
if (!Modifier.isFinal(field.getModifiers())) {
fields.add(field);
}
}
}
public static <T> T JsonToObj(JSONObject json, Class<T> clazz)
throws InstantiationException, ClassNotFoundException, IllegalAccessException {
Object entity = clazz.newInstance();
Iterator<?> keys = json.keys();
while (keys.hasNext()) {
try {
Object key = keys.next();
Object value = json.get(key.toString());
Field field = clazz.getField(key.toString());
field.setAccessible(true);
try {
field.set(entity, value);
} catch (IllegalArgumentException e) {
Class fieldClazz = Class.forName(field.getType().getCanonicalName());
if(fieldClazz.isEnum()){
field.set(entity, Enum.valueOf(fieldClazz, value.toString()));
}else if("UUID".equals(fieldClazz.getSimpleName())){
field.set(entity, UUID.fromString(value.toString()));
}else if("ArrayList".equals(fieldClazz.getSimpleName())){
JSONArray jsonArray = (JSONArray) value;
ArrayList<String> arrayList = new ArrayList<>();
for(int i = 0; i < jsonArray.size(); i++){
String s = (String) jsonArray.get(i);
arrayList.add(s);
}
field.set(entity, arrayList);
}else{
//TODO
throw new RuntimeException("fieldClazz is not added");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return (T)entity;
}
}
3. 使用代理模式实现日志切面的功能,具体表现为,将具体类的全类名,注册到程序中,当前类运行之前会输出方法名和入参,方法结束后会输出返回值,有错误则打印异常
- 在解决这个问题的时候,主要是使用了AOP的思想,使用动态代理帮我执行了日志的基本的实现
package com.dys.Logger2;
import org.junit.jupiter.api.Test;
public class AOPtest {
@Test
public void test() {
MathC calculator = new MathCalculator();
calculator.add(1, 21);
calculator.div(2, 3);
System.out.println("=========");
MathC Proxy = MathCProxy.getProxy(calculator);
Proxy.add(2, 12);
}
}
package com.dys.Logger2;
public interface MathC {
public int add (int i, int j );
public int sub (int i, int j );
public int mul (int i, int j );
public int div (int i, int j );
}
package com.dys.Logger2;
public class MathCalculator implements MathC{
@Override
public int add(int i, int j) {
// TODO Auto-generated method stub
return i+j ;
}
@Override
public int sub(int i, int j) {
// TODO Auto-generated method stub
return i-j ;
}
@Override
public int mul(int i, int j) {
// TODO Auto-generated method stub
return i*j ;
}
@Override
public int div(int i, int j) {
// TODO Auto-generated method stub
return i/j;
}
}
package com.dys.Logger2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class MathCProxy {
public static MathC getProxy(MathC calculator) {
ClassLoader loader = calculator.getClass().getClassLoader();
Class<?>[] interfaces = calculator.getClass().getInterfaces();
InvocationHandler hander = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("动态代理帮你执行");
System.out.println("【"+method.getName()+"】方法开始执行,使用的参数列表是【"+Arrays.asList(args)+"】");
Object result = method.invoke(calculator,args);
System.out.println("【"+method.getName()+"】方法开始结束,计算结果是【"+result+"】");
return result;
}
};
Object pro = Proxy.newProxyInstance(loader, interfaces, hander);
return (MathC)pro;
}
}
4. 结合单例设计模式或者工厂模式实现IOC的效果,具体表现为对象的注入容器和使用(选做:使用注解完成注入和取出)
package com.dys.IOCdemo;
public class AccountCencollert {
public static void main(String[] args) {
// IAccountService iaccount=new AccountServiceImpl();
IAccountService iaccount= (IAccountService) BeanFactory.getBean("accountService");
iaccount.save(); //运行结果:save成功一个账户.... 说明了成功调用了service
}
}
package com.dys.IOCdemo;
public class AccountServiceImpl implements IAccountService{
@Override
public void save() {
System.out.println("成功实现IOC反射.");
}
}
package com.dys.IOCdemo;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class BeanFactory {
private static Properties props;
//定义一个map容器,用于存放创建的对象
private static Map<String,Object> beans; //改进的代码============
static{
try {
//实例化对象
props = new Properties();
//获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("Bean.properties");
props.load(in);//加载其对应路径下的配置文件
// 以下是改进的代码=======================
//实例化容器
beans=new HashMap<String,Object>();
//取出配置文件中所有的key值
Enumeration<Object> keys = props.keys();
//遍历枚举
while(keys.hasMoreElements()){
//取出每个key
String key = keys.nextElement().toString();
//根据key取出对应的value (这里因为每个value值对应着类路径)
String beanPath = props.getProperty(key);
//反射创建对象
System.out.println(beanPath);
Object value = Class.forName("com.dys.IOCdemo.AccountServiceImpl").newInstance();
//把key和value存入容器中
beans.put(key,value);
}
}catch (Exception e){
throw new ExceptionInInitializerError("初始化properties失败!");
}
}
//随着代码的改进,我们就可以简化下面的获取bean对象的方法,如下代码
/**
* 根据bean的名称获取对象(单例)
*/
public static Object getBean(String beanName){
//通过Map容器对应key来获取对应对象
return beans.get(beanName); //这里通过Map容器中获取,这样就不会每次都创建一次实例!
}
package com.dys.IOCdemo;
public interface IAccountService{
public void save();
}
5.实现用户登陆状态的管理工具类,用户登陆进系统后保存用户的信息,用户访问页面资源或者请求时检查用户权限,用户权限使用List存储,可以增加或者减少。例如List内容是["/user/login", “/book/list”, “/user/manager.html”]则表示用户可以访问/user/login, /book/list接口和/user/manager.html页面
package com.dys.SessionDemo;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
public class SessionUtil {
private static final Long sessionMaxAge = 86400L;
private static class SessionUtilInner {
private static final SessionUtil SESSION_UTIL = new SessionUtil();
}
public static SessionUtil getSessionUtil() {
return SessionUtilInner.SESSION_UTIL;
}
private static ConcurrentHashMap<String, HttpSession> sessionMap;
static { //使用静态代码块提高代码效率
sessionMap = new ConcurrentHashMap<>();
}
public static ConcurrentHashMap<String, HttpSession> getSessionMap() {
sessionMap = cleanMap(sessionMap);
return sessionMap;
}
private static synchronized ConcurrentHashMap<String, HttpSession> cleanMap(
ConcurrentHashMap<String, HttpSession> map) {
if (map.size() < 1) {
return map;
}
Set<Entry<String, HttpSession>> entrySet = map.entrySet();
List<String> list = new ArrayList<>();
for (Entry<String, HttpSession> entry : entrySet) {
// 如果session过期了,就清除掉这个session
long max_age = sessionMaxAge * 1000L;
long time = new Date().getTime();
long creationTime = entry.getValue().getCreationTime();
long sessionAge = time - creationTime;
if (sessionAge > max_age) {
list.add(entry.getKey());
entry.getValue().setMaxInactiveInterval(1);
}
}
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
map.remove(list.get(i));
}
}
list = null;
return map;
}
public static synchronized void cleanOldSession(String userInfo) {
if (sessionMap != null && sessionMap.size() > 0) {
Set<Entry<String, HttpSession>> entrySet = sessionMap.entrySet();
String sessionKey = "";
for (Entry<String, HttpSession> entry : entrySet) {
if (StringUtils.isNotBlank(userInfo)
&& userInfo.equals((String) entry.getValue().getAttribute("userInfo"))) {
sessionKey = entry.getKey();
entry.getValue().setMaxInactiveInterval(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
if (StringUtils.isNotBlank(sessionKey)) {
sessionMap.remove(sessionKey);
}
}
}
}
大致上所有的作业如上,女朋友送走了以后再加点注释,然后把考核A给完成了。就酱~~