OA后端项目的总结
项目架构:springboot+jpa
第一、全局异常的处理
1.首先理解什么是全局异常:第发送http的请求的是否方法出现异常所以我们要进行全局异常处理
2.如何处理全局异常
第一步:添加注解在类上面 @ControllerAdvice
第二步:继承ResponseEntityExceptionHandler
第三步:重写ResopnseEntity<Object> handleExceptionInternal(Exception ex,Object body,HttpHeaders headers,WebRequest request){
return new ResponseEntity(“worng”,HttpStatus.NOT_EXTENDED)
}
第四步:@ExceptionHandler(value=Exception.class)
@ResponseBody
判断session
第二、日志的处理使用注解
1.在这个项目中我为什么使用注解对日志:aop配置日志代理,用于对日志的基本信息进行记录
2.怎么使用
第一步:在类上面添加注解
@Configuration
@Aspect
第二步:拦截注解 自定义方法
@Around(“@annotation(注解所在路径)”)
public ResultData check(ProceedingJoinPoint point){
ResultData resultData = null;
MethodSignature signature = signature.getMethod().getAnnotations();
//获取该方法上面的注解
Annotation[] annotation = signature.getMethod().getAnnotations();
for(int i = 0 ; I < annotation.length;i++){
if(annotation[i] instanceof 自定义注解的信息){
获取直接的信息
}
}
try{
resultData = (ResultData)point.proceed();
}catch(Exception e) {
//处理方法的异常的信息
}
//获取http请求过来的参数,就是为了获取到session对象
for(Object obj :point.getArgs){
if(!(arg instanceof HttpServletRequest))
}
}
如何自定义注解
在类上面添加@Target(ElementType.METHOD)\
@Retention(RetentionPolicy.RUNTIME)
注解的类 public @interface 注解的名字
定义注解的 方法 String success() default “”
第三、拦截器的使用
HandlerInterceptor
主要作用是 在方法前面执行在方法后面执行 在页面渲染执行
在方法之前执行:这个方法的作用主要是对象session的拦截
怎么将连接器注册到spring容器中
第一种方式通过:@Component
第二种方式通过
第一步:继承WebMvcConfigurerAdapter
第二步:重写方法
addInterceptors(InterceptorRegister register){
registery.addInterceptor(创建拦截器对象).addPathPatterns(“/**”)
super.addInterceptors(register )
}
第四、定时任务的的使用
什么是定时任务,在定义方法指定时间对业务进行处理我们叫定时任务
怎么做:
第一步:定义一个类在类上面添加注解@Component
第二步: 在类里面添加方法 在方法上面添加注解 @Scheduled
使用cron表达式:下面我介绍一下cron表达式
第一位是表示秒 0-59
第二位是表示分 0-59
第三位是表示时 0-23
第四位是表示天 1-31
第五位是表示月份 1-12
第六位是表示星期 1-7
第七位是表示年份
第五、cache的使用
第一步:定义一个ehcache.xml
<?xml version=”1.0” encoding=”utf-8”>
<ehcache>
<defaultCache
maxEntriesLocalHeap=”100”
eternal=”false”
timeToIdleSeconds = “120”
maxEntriesLocalDisk=”100000”
diskExpiryThreadIntervalSeconds=”120”
memoryStoreEvictionPolicy=”LRU”
>
<persistence strategy=”localTempSwap”>
</defalutCache>
<cache name="HelloWorldCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="5"
timeToLiveSeconds="5"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
</ehcache>
第二步:导入依赖
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2</version>
</dependency>
第三步: @Configuration
@PropertySource(value={“classpath:application.properties”},encoding=”utf-8”)
定义一个类 在类里面添加一个方法
@Bean
Public CacheManger getCacheManger(){
ClassPathResource classPathResource = new ClassPathResource(“ehcache,xml”)
Try{
cacheManger = CacheManger.create(classPathResource.getInputStream)
}catch(Exception e){
}
return cacheManger
}
第四步: //封装cache方法
// 1. 创建缓存管理器
CacheManager cacheManager = CacheManager.create("./src/main/resources/ehcache.xml");
// 2. 获取缓存对象
Cache cache = cacheManager.getCache("HelloWorldCache");
// 3. 创建元素
Element element = new Element("key1", "value1");
// 4. 将元素添加到缓存
cache.put(element);
// 5. 获取缓存
Element value = cache.get("key1");
System.out.println(value);
System.out.println(value.getObjectValue());
// 6. 删除元素
cache.remove("key1");
Dog dog = new Dog(1L, "taidi", (short)2);
Element element2 = new Element("taidi", dog);
cache.put(element2);
Element value2 = cache.get("taidi");
Dog dog2 = (Dog) value2.getObjectValue();
System.out.println(dog2);
System.out.println(cache.getSize());
// 7. 刷新缓存
cache.flush();
// 8. 关闭缓存管理器
cacheManager.shutdown();
第六、springboot跨域的处理
第一步:在main方法所在的类中寄存WebMvcConfigurerAdapte
第二步:重写 addCorsMappings(CorsRegistry register){
register.addMappper(“/**”).allowedHeaders(“*”).addowedMethod(“*”).allowedOrigins(
“*”)
}
第七.加密与解密
1.为什么出现加密的过程: 就是因为防止信息被一些手段进行破解
2.如何自定义对信息进行加密处理
2.1借助于sun包
2.2 static{
Try{
KeyGenerator generator = KeyGenerator.getInstance(“DES”)
Generator.init(new SecureRandom(Key_STR.getBytes()))
Key = generator.geneartekey();
generator =null
}catch(Exceptipon o){
Throw new RuntimeException()
}
}
//加密的方法
public static String getEncryptString(String str){
BASE64Encodeer base64Encoder = new BASE64Encoder();
try{
byte[] strbytes = str.getBytes(“UTF-8”)
Cipjer cipher = Cipher.getInstance(“DES”)
cipjer.init(Cipher.ENCRYPT_MODE,key)
byte[] encryptStrBytes =cipher.doFinal()
return base64Encoder.encode(encryptStrBytes)
}catch(Exception e){
Throw new RuntimeException();
}
}
//解密的方法
public static String getDecryptString(String str){
BASE64Decoder base64Decoder = new BASE64Decoder();
Try{
byte[] strBytes = base64Decoder.decodeBuffer(str)
Cipher cipher = Cipher.getInstance(“DES”)
cipher.init(Cipher.DECRYPT_MODE,key)
byte[] decryptStrBytes = cipher.doFinal(strBytes)
return new String(decryptStrBytes,”UTF-8”)
}catch(Exception e){
}
}
第八、怎么解析xml
第一步:根据文件名字找到文件所在文件的类路径
private String getFile(String fileName){
String path = null;
try{
path = this.getClass().getClassLoader().getResource(fileName).getPath();
logger.info("parse success");
}catch (Exception e){
logger.error("parse error");
}
return path;
}
第二步:解析文件方法指定的容器内
public static void parse(File file,List<Bean> contaier)throws Exception{
if(file.isDirectory()){
SAXReader reader = new SAXReader();
File[] listFiles =file.listFiles();
for(int i = 0;i < listFiles.length;i++){
if(listFiles[i].getName().endsWith(".xml")) {
Document document = reader.read(listFiles[i]);
parseXmlDatas(document.getRootElement().elements(), contaier, "user-permission-grade");
}else{
continue;
}
}
}
}
详细解析
首先判断该文件传入过来是否是文件夹,如果是文件夹,建立解析器,通过文件夹获取到下面的文件,然后遍历文件(首先判断该文件的后缀名是否已.xml),如果是已.xml结束,解析文件里面的内容 通过文档对象拉到文档对象(其实文档对象就是xml里面的内容),然后解析文件里面的内容
第三步:解析文件里面的内容
public static void parseXmlDatas(List<Element> elementList,List container,String firstElements){
for(Element dataElement: elementList){
if(dataElement.getName().equals(firstElements)){
List<Element> dataList = dataElement.elements();
parseXmlData(dataElement.elements(),container);
}
}
}
详细解析
拿到文件对象,第一步遍历标签,判断该根元素是否已指定的元素开始,如果是解析根元素下面的子元素,然后解析数据
public static void parseXmlData(List<Element> elementsList,List<Bean> container){
Bean bean = new Bean();
for(Element data:elementsList){
String name = data.getName();
if("name".equalsIgnoreCase(name)){
bean.setName((String)data.getData());
}else if("value".equalsIgnoreCase(name)){
System.out.println(name);
bean.setValue(Integer.parseInt((String)data.getData()));
} //获取属性 //data.attgit ributeValue("id")
}
container.add(bean);
}
详细解析
遍历元素,获取元素所在文件中的标签的名字,然后对标签里面的内容进行封装成类对象。
第九、如何根据数据库的信息自动生成实体类
第十,如何根据实体类自动生成数据库的类信息
第十一、JPA详解
1. 在类上面
@Entity:表示该类是一个实体类对象
@Table 指定生成数据库的表的名字
注解里面的属性指定
name:指定生成数据库表的名字
2. 在属性上面
@Id: 表示该属性是主键
@GeneraterValue(strategy = GenerationType.IDENTITY)
两个配合使用,表示该主键是自增长
@Column(name=””)
表示指定生成数据中每个字段的名字
一对一
这个会在指定类中生成一个外键
@OneToOne(fetch = Fetch.lazy,cascade = CascadeType.All)
@JoinColumn(name=“”)
name=””表示指定的名字
一对多
这个会在多的一方生成外键
@OneToMany(fetch = Fetch.lazy,cascade = CascadeType.All)
@ JoinColumn(name=“”)
@Fetch(FetchMode.SUBSELECT)=
多对多的
@ManyToMany(fetch = Fetch.lazy,cascade = CascadeType.All)
@JoinTable(name=“”,joinColums={@JoinColumn(name=””)}
,inverseJoinColumns ={@JoinColumn(name=””)}
)
该类所对应的菜单类的信息
List<Menu> menu ;
3. 在方法上面
@JsonBackReference