VO
Value Object / View Object 专门为视图定制的模型
如:
class MessageVO {
private int id;
private String title;
private String pubDate;
private String nickname;
private String[] filenames;
public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
public MessageVO(Message message) {
this.id = message.getId();
this.title = message.getTitle();
this.pubDate = format.format(message.getPubDate());
this.nickname = message.getPubUser().getNickname();
}
}
DTO
Data Transfer Object 数据传输对象
分层架构
分层架构(事务脚本模式) 用户有一个请求 在业务中就有一个方法 就有一个事务
微服务架构/六边形架构
反射工具类
clazz.getField(String arg) 得到目标类中指定的某个public属性对应的Field对象
clazz.getDeclaredField(String arg) 同getField,但不局限于public修饰,只要是目标类中声明的属性均可
f.setAccessible(true) 设置属性可修改
f.get(target) 拿到对象实例的 域成员的值
例子1:根据字段名查找字段的类型
先
/**
* 根据字段名查找字段的类型
* @param target 目标对象
* @param fieldName 字段名
* @return 字段的类型或null
*/
public static Class<?> getFieldType(Object target, String fieldName) {
Class<?> clazz = target.getClass();
String[] fs = fieldName.split("\\.");
try {
for (int i = 0; i < fs.length - 1; ++i) {
Field f = clazz.getDeclaredField(fs[i]);
target = f.getType().newInstance();
clazz = target.getClass();
}
return clazz.getDeclaredField(fs[fs.length - 1]).getType();
}
catch (Exception e) {
return null;
}
}
例子2:获取对象所有字段的名字
/**
* 获取对象所有字段的名字
* @param obj 目标对象
* @return 字段名字的数组
*/
public static String[] getFieldNames(Object obj) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
List<String> fieldNames = new ArrayList<>();
for (int i = 0; i < fields.length; i++) {
if ((fields[i].getModifiers() & Modifier.STATIC) == 0) {
fieldNames.add(fields[i].getName());
}
}
return fieldNames.toArray(new String[fieldNames.size()]);
}
例子3:通过反射取对象指定字段(属性)的值
1.根据传入的target对象得到target的类信息
2.将传入的字段名字根据.分割成字符串数组
3.限定小于fs.length() - 1之间循环 如果字符串长度为2 循环一次
4.用clazz根据字段名用getDeclaredField()方法拿到字段对象
5.将字段对象设置为可以修改的
6.f.get(target)字段对象根据传入的target对象拿到对应target实例中参数的值,如果是基本类型int 就拿到对应的值23,如果是类Car,就拿到对象car
7.根据对应属性的值得到对应字段值对象的类信息 如: String 对应 String的类信息, 自己定义的Car类 得到对应的Car类的类信息
8.如果循环未结束,继续向下。如Person中有Car这个对象属性,拿到之后向下继续得到Engine对象。
9.若循环结束 或 字符串数组长度为1,直接fs[fs.length - 1]得到对应的字段,设置可以访问权限
10.返回字段的值
/**
* 通过反射取对象指定字段(属性)的值
* @param target 目标对象
* @param fieldName 字段的名字
* @throws 如果取不到对象指定字段的值则抛出异常
* @return 字段的值或null
*/
public static Object getValue(Object target, String fieldName) {
Class<?> clazz = target.getClass();
String[] fs = fieldName.split("\\.");
try {
for (int i = 0; i < fs.length - 1; i++) {
Field f = clazz.getDeclaredField(fs[i]);
f.setAccessible(true);
target = f.get(target);
clazz = target.getClass();
}
Field f = clazz.getDeclaredField(fs[fs.length - 1]);
f.setAccessible(true);
return f.get(target);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
例子4:通过反射给对象的指定字段赋值
/**
* 通过反射给对象的指定字段赋值
* @param target 目标对象
* @param fieldName 字段的名称
* @param value 值
* @throws
*/
public static void setValue(Object target, String fieldName, Object value) {
Class<?> clazz = target.getClass();
String[] fs = fieldName.split("\\.");
try {
for (int i = 0; i < fs.length - 1; i++) {
Field f = clazz.getDeclaredField(fs[i]);
f.setAccessible(true);
Object val = f.get(target);
if (val == null) {
Constructor<?> c = f.getType().getDeclaredConstructor();
c.setAccessible(true);
val = c.newInstance();
f.set(target, val);
}
target = val;
clazz = target.getClass();
}
Field f = clazz.getDeclaredField(fs[fs.length - 1]);
f.setAccessible(true);
f.set(target, value);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
安全性
基本验证
web.xml配置
配置安全性约束
<security-constraint>
指定需要安全约束的资源
<web-resource-collection>
<web-resource-name>protected</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>DIGEST</auth-method>
<realm-name>protected</realm-name>
</login-config>
tomcat-users.xml配置
<!-- AA - Authentication / Authorization -->
<!-- What you konw? -->
<!-- What you have? -->
<!-- Whom you are? -->
<role rolename="authorizedUser" />
<role rolename="admin" />
<role rolename="manager" />
<role rolename="emp" />
<user username="jack" password="123456" roles="admin,manager" />
客户端证书验证
如果创建了keystore
rm .keystore
第一步:
keytool -genkey -alias tomcat -keyalg RSA
第二步:
keytool - certreq -alias tomcat -file tomcat.csr
第三步:
keytool -importcert -alias tomcat -file tomcat.cer