相关文章:
SpringAOP配置切面报错
nginx代理静态图片
spring和redis的整合
一、字典值的优化
在项目中,枚举字典表做了一些优化,在程序启动的时候将数据一次性加载到内存,当字典表变化时(增删改)把内存数据重新加载一次,这个功能是通过AOP结合自定义注解完成的。
1.初始化代码
@Component
public class DictParamUtil {
@Autowired
private IDictTypeDao typeDao;// 注入字典类型DAo接口
private Log logger = LogFactory.getLog(DictParamUtil.class);
private Map<Integer, Map<Integer, String>> dicMap = new HashMap<>();
/**
* 初始化下拉框列表
*/
@PostConstruct
public void initDicMap(){
// 清空下拉框Map
dicMap.clear();
// 把所有字典类型取出来
List<DictType> typeList = typeDao.queryAllObj(new DictTypeCond());
Map<Integer,String> map = null;
DictCond cond = new DictCond();
List<Dict> dictList = null;
for (DictType dictType : typeList) {
map = new HashMap<Integer, String>();
// 根据字典类型查询所有的字典值
cond.setType_code_c(dictType.getType_code());// 条件:类型编码
dictList = dictService.queryAllObj(cond);
for (Dict dict : dictList) {
map.put(dict.getData_key(), dict.getData_value());
}
dicMap.put(dictType.getType_code(), map);
}
logger.info("-------------------------字典值下拉框初始化完成-------------------------");
}
}
每次对字典类型和字典值修改之后重新初始化
2.定义切面
@Component
@Aspect
public class DicAspect {
public Log logger = LogFactory.getLog(getClass());
@Autowired
private DictParamUtil util;
@After("within(com.cms.sys.dict*.service.impl..*) && @annotation(dic)")
public void execute(JoinPoint point , DicAnnotation dic){
util.initDicMap();
logger.info("------------------" + point.getSignature() + "初始化字典值------------------");
}
}
3.自定义注解
@Target(ElementType.METHOD) // 用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface DicAnnotation {
}
二、对轮播图的优化
轮播图的数据较多,保存到redis中。当请求首页的时候,先去redis中查找缓存是否存在,不存在的话通过HttpClient请求数据接口api得到轮播图数据。这个数据是json格式的,再转成list集合。当对轮播图进行修改操作时会清空redis。也是采用AOP+自定义注解的方式完成的。
1.代码实现
/**
* @功能描述 首页相关业务逻辑实现
* @author zhaoj
*/
@Service
public class HomeServiceImpl implements IHomeService {
@Autowired
private HttpUtil httpUtil;// 注入发送请求的工具类
@Autowired
private RedisTemplate<String,String> template;
private Log logger = LogFactory.getLog(getClass());
// @Override
// public List<Banner> queryBanners() {
//
// Jedis jedis = new Jedis("ip",6379);
// // 得到PC端的轮播图,1-PC端,2-M站
// String str = jedis.get(ApplicationConstant.BANNER_PC);
//
// // 如果缓存中没有轮播图相关信息,调用接口查询
// if( str == null){
// str = httpUtil.getTextOfGet("banner/list?type=1");
// logger.info("-------------------------进入查询------------------------------");
// jedis.set(ApplicationConstant.BANNER_PC, str);
// jedis.close();
// }
//
// Banner[] banners = GenerateJsonUtil.generateObj(str, Banner[].class);
// // 将数组转成集合list
// List<Banner> list = Arrays.asList(banners);
//
// return list;
// }
@Override
public List<Banner> queryBanners() {
ValueOperations<String,String> opsForValue = template.opsForValue();
// 得到PC端的轮播图,1-PC端,2-M站
String str = (String) opsForValue.get(ApplicationConstant.BANNER_PC);
// 如果缓存中没有轮播图相关信息,调用接口查询
if( str == null ){
str = httpUtil.getTextOfGet("banner/list?type=1");
logger.info("-------------------------进入查询------------------------------");
logger.info("-------------------------"+str+"------------------------------");
opsForValue.set(ApplicationConstant.BANNER_PC, str);
}
Banner[] banners = GenerateJsonUtil.generateObj(str, Banner[].class);
// 将数组转成集合list
List<Banner> list = Arrays.asList(banners);
return list;
}
}
2.切面类
/**
* 轮播图切面类
* @author zhaoj
*/
@Component
@Aspect
public class BannerAspect {
@Autowired
private RedisTemplate<String,String> redisTemplate;
private Log logger = LogFactory.getLog(getClass());
@After("within(com.cms.banner.service..*) && @annotation(ann)")
public void clearBannerRedis(JoinPoint point ,BannerAnnotation ann){
ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
// 清除redis
opsForValue.set(Constant.BANNER_PC, null);
logger.info("执行了" + point.getSignature() + "清空redis !!!");
}
}
3.请求工具类
/**
* 连接api的工具类
* @author zhaoj
*/
@Component
public class HttpUtil {
@Autowired
private Config config;
private Log logger = LogFactory.getLog(getClass());
/**
* get请求返回响应内容
* @param uri
* @return
*/
public String getTextOfGet(String uri){
// 创建HttpClient
HttpClient client = HttpClients.createDefault();
// 创建get请求
HttpGet get = new HttpGet(config.getApi_url() + uri);
String text = "";
try {
// 客户端连接请求
HttpResponse response = client.execute(get);
// 得到响应的实体
HttpEntity entity = response.getEntity();
// 得到实体内容
text = EntityUtils.toString(entity);
} catch (ClientProtocolException e) {
logger.info("get请求抛出ClientProtocolException异常!");
e.printStackTrace();
} catch (IOException e) {
logger.info("get请求抛出IOException异常!");
e.printStackTrace();
} finally {
// 必须释放资源
get.releaseConnection();
}
return text;
}
/**
* 得到post请求的响应结果
* @param uri 请求路径
* @param map 请求体携带的参数
* @return
*/
public String getTextOfPost(String uri, Map<String,String> map){
// 创建HttpClient
HttpClient client = HttpClients.createDefault();
// 创建post请求
HttpPost post = new HttpPost(config.getApi_url() + uri);
// 创建名值对list
List<NameValuePair> list = new ArrayList<NameValuePair>();
BasicNameValuePair basic = null;
String text = "";
// 遍历map,向list中添加数据
for (Map.Entry<String, String> entry : map.entrySet()) {
// BasicNameValuePair implements NameValuePair
basic = new BasicNameValuePair(entry.getKey(), entry.getValue());
list.add(basic);
}
try {
// 把参数编码到表单实体中
UrlEncodedFormEntity entityPost = new UrlEncodedFormEntity(list,"UTF-8");
// 把表单实体放到请求中
post.setEntity(entityPost);
// 用客户端去执行post请求
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();// 从响应中取出响应实体
text = EntityUtils.toString(entity);
} catch (IOException e) {
logger.info("post请求抛出IOException异常!");
e.printStackTrace();
} finally {
post.releaseConnection();
}
return text;
}
}
4.json工具类
/**
* 有关操作json的工具类
* @author zhaoj
*/
public class GenerateJsonUtil {
private static Log logger = LogFactory.getLog(GenerateJsonUtil.class);
/**
* 将json格式的字符串转成对象
* @param json 待转的字符串
* @param clazz 对象的class
* @return
*/
public static <T> T generateObj(String json, Class<T> clazz) {
T obj = null;
ObjectMapper mapper = new ObjectMapper();
try {
obj = mapper.readValue(json, clazz);
} catch (JsonParseException e) {
logger.info("字符串转对象抛出JsonParseException异常!!!");
e.printStackTrace();
} catch (JsonMappingException e) {
logger.info("字符串转对象抛出JsonMappingException异常!!!");
e.printStackTrace();
} catch (IOException e) {
logger.info("字符串转对象抛出IOException异常!!!");
e.printStackTrace();
}
return obj;
}
/**
* 将对象转换成json格式的字符串
* @param obj 对象
* @return
*/
public static String generateJson(Object obj){
String json = "";
ObjectMapper mapper = new ObjectMapper();
try {
json = mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
logger.info("对象转字符串抛出JsonProcessingException异常!!!");
e.printStackTrace();
}
return json;
}
}
三、首页静态化
通过httpClient请求动态首页,获取页面内容,把它写到nginx代理过的文件夹下。
1.代码实现
@Serivce
public class HomeServiceImpl implements HomeService{
@Autowired
private HttpUtil util;
public Log logger = LogFactory.getLog(getClass());
@Override
public void runStatic() {
// 得到首页的文本信息
String text = util.getTextOfGet("home/index.do");
// 替换字符
text = text.replaceAll("/resources/", "http://img.power.static/");
logger.info(text);
// 保存到文件中
// 保存的地址
String dest = "D:/img/home/index.html";
File file = new File(dest);
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
// 装饰者模式,只关闭高级流
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
writer.write(text);
} catch (FileNotFoundException e) {
logger.info("--------------------复制文件抛出FileNotFoundException--------------------");
e.printStackTrace();
} catch (IOException e) {
logger.info("--------------------复制文件抛出IOException--------------------");
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.nginx配置
在nginx代理的文件夹下
新建一个文件夹static,存放首页需要的css,js,icon
新建一个文件夹home,存放首页index.html
server {
listen 80;
server_name img.power.home;
#只过滤以.html 结尾的请求
location ~ .*\.(html)$ {
root D:/img/home;
index index.html;
}
#其它请求
location / {
proxy_pass http://localhost;
proxy_connect_timeout 500ms;
}
}