我遇到的问题与逻辑有关,而不是技术,这是一个场景,(我使用的是Spring + Hibernate)
我需要从数据库中读取一些数据,以便在每次获取请求时返回页面,但我认为有些黑客攻击,如果使用某些脚本有人非常频繁地重新加载页面,这将导致许多调用服务器,为此我想读取数据并将它们放在全局变量或类变量中,通过这样做我最终编写非常奇怪的代码许多全局变量和愚蠢的方式来给它们初始值,就像一个变量user-status这是一个字节类型变量我给了-2作为初始值,这样我的内部逻辑就可以理解没有从数据库为这个变量设置值,下面是我的代码
@Controller
/* @Secured("hasRole('ROLE_USERS')") */
@RequestMapping("member")
public class ApplyRoles {
@Autowired
private UserInformationForAccessApplication checkUserStatus;
// we will initialize variables to avoid auto-initialize by constructor
private byte userStatus = Constant.IntializationOfGlobalVariable.GLOBALINIT,
requesttype = Constant.IntializationOfGlobalVariable.GLOBALINIT,
access = Constant.IntializationOfGlobalVariable.GLOBALINIT;
Map<String, Object> accessnrole;
Map<String, String> country;
Map<String, String> roleArray;
@Autowired
StudentEnrollmentApplication enrollmentApplication;
@Autowired
SystemProperties systemProperties;
@Autowired
EmployeeEnrollmentApplicationResume employeeEnrollmentApplicationResume;
@Autowired
AccessEnrollmentProcessing accessEnrollmentProcessing;
private String role = Constant.IntializationOfGlobalVariable.ROLENOTSET,
fname, lname;
@RequestMapping(value = "/user", method = RequestMethod.GET)
public String checkingUserStatus(Model model, HttpSession session,
Authentication authentication) {
String sessionemail = "yashprit@gmail.com";// (String) session
// .getAttribute(Constant.SessionAttributes.LOGGEDINUSER);
// first check global value, if found set than don't fetch from database
if (userStatus == Constant.IntializationOfGlobalVariable.GLOBALINIT) {
// get user status from MySQL Database
userStatus = checkUserStatus.checkStatus(sessionemail).get(0);
if (!(userStatus == Constant.UserRoleApplicationStatus.NOTAPPLIED)) {
access = checkUserStatus.checkStatus(sessionemail).get(1);
model.addAttribute(Constant.SystemName.ACCESS, access);
}
}
if (!(userStatus >= Constant.UserRoleApplicationStatus.NOTAPPLIED || userStatus <= Constant.UserRoleApplicationStatus.REJECTED)) {
model.addAttribute("error", "User status is not avaible");
return "redirect:error/pagenotfound";
} else if (userStatus == Constant.UserRoleApplicationStatus.NOTAPPLIED) {
if (requesttype == Constant.IntializationOfGlobalVariable.GLOBALINIT) {
// get request type from MongoDB database
requesttype = checkUserStatus.getRequestType(sessionemail);
}
if (!(requesttype == Constant.RequestType.NORMALEBIT || requesttype == Constant.RequestType.INVITEBIT)) {
model.addAttribute("error",
"Facing Technichal Issue, Please try again");
return "redirect:error/pagenotfound";
}
if (requesttype == Constant.RequestType.INVITEBIT) {
if (!(Byte.parseByte((String) accessnrole
.get(Constant.SystemName.ACCESS)) == Constant.Access.USERBIT)) {
accessnrole = checkUserStatus
.getAccessAndRole(sessionemail);
}
if (accessnrole.get(Constant.SystemName.ACCESS).equals(
Constant.Database.ERRORMESSAGE)
|| accessnrole.get(Constant.SystemName.ROLE).equals(
Constant.Database.ERRORMESSAGE)) {
model.addAttribute("error",
"Facing Technichal Issue, Please try again");
return "redirect:error/pagenotfound";
}
model.addAttribute(Constant.SystemName.ACCESSNROLE, accessnrole);
model.addAttribute(Constant.SystemName.REQUESTTYPE, requesttype);
}
}
model.addAttribute(Constant.SystemName.USERSTATUS, userStatus);
return "member/user";
}
}
为了避免全局变量我想起了起诉cookie,因为我不想在同一个会话中重新加载每个页面上调用数据库,一旦它加载一个会话而不是我不必调用数据库。
非常感谢能够帮助重新设计上面代码的任何内容
谢谢
答案 0 :(得分:1)
你有两件事正在考虑,如果我错了,请正确地说,但是:
第一个可以使用缓存在春天使用任何给定方法的注释来解析。该文档可用here。
第二个有点棘手,除非你发现性能问题,否则我现在就离开它。它可以在Spring中完成,并利用HTTP标头中的HTTP协议和缓存控件来通知浏览器缓存响应的时间。
答案 1 :(得分:0)
您正在考虑的是“缓存”。它是一种标准的计算机科学服务方式,只要有计算机,他们就一直在研究如何使用缓存。
您可能想要对这个主题进行一些阅读。我通过Googling“缓存教程java”http://javalandscape.blogspot.com/2009/01/cachingcaching-algorithms-and-caching.html
找到了这个简单来说(一个项目缓存)你想要的是存储你最近花了一些时间来提出的一些数据对象。但是您还必须拥有某种标识符,以便您可以判断下一个请求是否要求相同的数据。如果不是,你必须做所有的工作。如果它是相同的数据,您只需再次返回。
因此,在这个简单的情况下,算法的工作原理如下:
if (storedData != null && storedRequestInfo == userRequest.requestInfo) {
return storedData;
}
storedData = youCalculateTheRequestedData();
storedRequestInfo = userRequest.requestInfo;
return storedData;
它不是任何真正的编程语言,只是向您展示它是如何工作的。
requestInfo是用于查找数据库内容的请求中的任何内容。您可以在任何计算后将其保存在storedRequestInfo中。
这表明它将一些数据返回给用户,这就是storedData。
这是一个简单的单元素缓存。
(为了对此进行扩展,您可以将storedRequestInfo和storedData存储在会话中,最后为每个用户存储其中一个。您还可以使用java Map并存储一堆storedData。问题是决定如何限制你的内存使用。如果你为每个用户存储了太多这些内存,你会耗尽太多的内存。所以你要限制每个用户可以拥有的数量或者数量。然后你必须决定哪一个当它变得太大时删除。在简单的情况下,你总是删除存储的并存储一个新的。
我注意到你的评论。在我上面使用的术语中,ECache只是一个很棒的地图。我不知道它是否自然会依赖于会话,但可以通过将会话ID添加到缓存键来实现。)