shiro+spring相关配置
首先pom中添加所需jar包:
<!-- shiro start -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
<!-- shiro end -->
一、在web.xml配制shiroFilter
<!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->
<!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->
<!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->
<!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
二、java代码编写
1.User.java
package isa.blog.bin.model; import java.io.Serializable;
import java.util.Date; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import org.hibernate.annotations.GenericGenerator; @Entity
public class User implements Serializable {
private static final long serialVersionUID = -5312120825533005238L; @Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid",strategy="uuid")
private String id; @Column(unique = true)
private String userName; private String password; private Date createTime; private String email; @ManyToOne
@JoinColumn
private Role role; public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public Role getRole() {
return role;
} public void setRole(Role role) {
this.role = role;
} }
2.Role.java
package isa.blog.bin.model; import java.io.Serializable; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id; import org.hibernate.annotations.GenericGenerator; @Entity
public class Role implements Serializable {
private static final long serialVersionUID = -3431097890965814550L; @Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid",strategy="uuid")
private String id; private String roleName; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} }
3.Permission.java
package isa.blog.bin.model; import java.io.Serializable; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import org.hibernate.annotations.GenericGenerator; @Entity
public class Permission implements Serializable {
private static final long serialVersionUID = 7808624074545962407L; @Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid",strategy="uuid")
private String id; private String permissionName; @ManyToOne
@JoinColumn
private Role role; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPermissionName() {
return permissionName;
} public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
} public Role getRole() {
return role;
} public void setRole(Role role) {
this.role = role;
}
}
4.UserDao.java
package isa.blog.bin.dao; import org.springframework.data.jpa.repository.JpaRepository; import isa.blog.bin.model.User; public interface UserDao extends JpaRepository<User, String> {
User findByUserNameAndPassword(String userName, String password);
User findOneByUserName(String userName);
}
5.PermissionDao.java
package isa.blog.bin.dao; import java.util.Set; import org.springframework.data.jpa.repository.JpaRepository; import isa.blog.bin.model.Permission;
import isa.blog.bin.model.Role; public interface PermissionDao extends JpaRepository<Permission, String> {
Set<Permission> findByRole(Role role);
}
6.MyRealm.java
package isa.blog.bin.commons; import java.util.HashSet;
import java.util.Set; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import isa.blog.bin.dao.PermissionDao;
import isa.blog.bin.dao.UserDao;
import isa.blog.bin.model.Permission;
import isa.blog.bin.model.User; @Transactional
public class MyRealm extends AuthorizingRealm{
@Autowired
private UserDao userDao;
@Autowired
private PermissionDao permissionDao; /**
* 为当前登录的用户授予角色和权限
*/
@Override
public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName = (String)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
try{
authorizationInfo.addRole(userDao.findOneByUserName(userName).getRole().getRoleName());
Set<Permission> permissions = permissionDao.findByRole(userDao.findOneByUserName(userName).getRole());
Set<String> strs = new HashSet<String>();
for (Permission permission : permissions) {
strs.add(permission.getPermissionName());
}
authorizationInfo.addStringPermissions(strs);
}catch(Exception e){
e.printStackTrace();
}
return authorizationInfo;
} /**
* 验证当前登录的用户
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName = (String)token.getPrincipal();
User user = userDao.findOneByUserName(userName);
if(user!=null){
AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(),"xx");
return authcInfo;
}else{
return null;
}
} }
三、配置文件applicationContext-shiro.xml
注意web.xml引入形式为:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
</context-param>
applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/> <!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java -->
<bean id="myRealm" class="isa.blog.bin.commons.MyRealm"/>
<!-- 踢出用户 -->
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO" />
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO" />
</bean>
<!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->
<!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->
<!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
<property name="sessionManager" ref="sessionManager" />
<!-- 使用下面配置的缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
</bean> <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
<!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
<property name="loginUrl" value="/views/login.html"/>
<!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) -->
<!-- <property name="successUrl" value="/index.html"/> -->
<!-- 用户访问未对其授权的资源时,所显示的连接 -->
<!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp -->
<property name="unauthorizedUrl" value="/unauthorized.html"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<!-- 此处可配合我的这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/12172839 -->
<!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 -->
<!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->
<!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
<property name="filterChainDefinitions">
<value>
/frame/user/login/** = anon
/frame/user/register/** = anon
/frame/kaptcha** = anon /css/** = anon
/img/** = anon
/js/** = anon
/json/** = anon
/Scripts/** = anon /views/login.html = anon
/views/register.html = anon # /frame/essay = roles[member]
# /views/addBlog.html = roles[admin]
# /frame/deleteEssay/** = perms[删除博客]
# /frame/deleteEssay/** = roles[admin] # 必须放在最后
/** = authc
</value>
</property>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 -->
<!-- 配置以下两个bean即可实现此功能 -->
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run -->
<!-- 由于本例中并未使用Shiro注解,故注释掉这两个bean(个人觉得将权限通过注解的方式硬编码在程序中,查看起来不是很方便,没必要使用) -->
<!--
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
--> </beans>
以下代码根据实际项目更改
UserController.java
package isa.blog.bin.controller; import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map; import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer; import isa.blog.bin.commons.JsonUtil;
import isa.blog.bin.commons.Result;
import isa.blog.bin.dto.UserDto;
import isa.blog.bin.service.UserService; @RestController
@RequestMapping(value="/frame")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private Producer producer; private Map<String, String> map; @RequestMapping(value="/user/register/{kaptchaCode}", method=RequestMethod.POST, produces=JsonUtil.JSON)
public Result register(@RequestBody UserDto userDto, @PathVariable String kaptchaCode) {
return userService.register(userDto, map, kaptchaCode);
} @RequestMapping(value="/user/oneUser/{userId}", method=RequestMethod.GET, produces=JsonUtil.JSON)
public Result getOneUser(@PathVariable String userId) {
return userService.getOneUser(userId);
} @RequestMapping(value="/user/login/{userName}/{password}/{kaptchaCode}", method=RequestMethod.GET, produces=JsonUtil.JSON)
public Result login(@PathVariable String userName, @PathVariable String password, @PathVariable String kaptchaCode) throws UnsupportedEncodingException {
return userService.login(URLDecoder.decode(userName, "UTF-8"), password, map, kaptchaCode);
} @RequestMapping(value="/user/logout", method=RequestMethod.GET, produces=JsonUtil.JSON)
public void logout() {
userService.logout();
} @RequestMapping(value="/user/userDetails_userName", method=RequestMethod.GET, produces=JsonUtil.JSON)
public Result getOneUserName() {
return userService.getOneUserName();
} @RequestMapping(value="/user/userDetails", method=RequestMethod.GET, produces=JsonUtil.JSON)
public Result getOneUserDetails() {
String userId = userService.currentUserId();
return userService.getOneUser(userId);
} @RequestMapping(value="/user/updateUserDetails", method=RequestMethod.POST, produces=JsonUtil.JSON)
public Result updateUserDetails(@RequestBody UserDto userDto) {
String userId = userService.currentUserId();
return userService.updateUserDetails(userId, userDto);
} @RequestMapping("/kaptcha")
public void initCaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String capText = producer.createText();
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
BufferedImage bi = producer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
String kaptchaCode = (String)session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
map = new HashMap<String, String>();
map.put("kaptchaCode", kaptchaCode);
out.close();
}
} }
UserService.java
package isa.blog.bin.service; import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import isa.blog.bin.commons.MD5Util;
import isa.blog.bin.commons.Result;
import isa.blog.bin.dao.UserDao;
import isa.blog.bin.dto.UserDto;
import isa.blog.bin.model.User; @Service
@Transactional
public class UserService {
ModelMapper modelMapper = new ModelMapper();
@Autowired
private UserDao userDao;
@Autowired
private SessionDAO sessionDAO; /**
* 注册
* @param userDto
* @param map
* @param kaptchaCode
* @return
*/
public Result register(UserDto userDto, Map<String, String> map, String kaptchaCode) {
Result result = new Result();
if (!map.get("kaptchaCode").equals(kaptchaCode)) {
result.setSuccess(false);
result.setMessage("验证码错误");
return result;
}
User user = userDao.findOneByUserName(userDto.getUserName());
if (user != null) {
result.setSuccess(false);
result.setMessage("用户名已存在");
return result;
}
user = modelMapper.map(userDto, User.class);
user.setPassword(MD5Util.MD5(userDto.getPassword()));
user.setCreateTime(new Date());
userDao.save(user);
result.setId(user.getId());
result.setSuccess(true);
result.setMessage("注册成功");
return result;
} /**
* 获取一个用户详情
* @param userId
* @return
*/
public Result getOneUser(String userId) {
Result result = new Result();
User user = userDao.findOne(userId);
UserDto userDto = modelMapper.map(user, UserDto.class);
List<UserDto> datas = new ArrayList<UserDto>();
datas.add(userDto);
result.setSuccess(true);
result.setDatas(datas);
return result;
} /**
* 登录
* @param userName
* @param password
* @param map
* @param kaptchaCode
* @return
*/
public Result login(String userName, String password, Map<String, String> map, String kaptchaCode) {
Result result = new Result();
if (!map.get("kaptchaCode").equals(kaptchaCode)) {
result.setSuccess(false);
result.setMessage("验证码错误");
return result;
} Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName, MD5Util.MD5(password));
//踢除用户
this.kickOutUser(token);
try{
subject.login(token);
Session session = subject.getSession();
System.out.println("sessionId:"+session.getId());
System.out.println("sessionHost:"+session.getHost());
System.out.println("sessionTimeout:"+session.getTimeout());
result.setMessage("登录成功");
System.out.println(userName+"登录成功");
List<UserDto> userDtos = new ArrayList<UserDto>();
User user = this.userDao.findOneByUserName(userName);
userDtos.add(modelMapper.map(user, UserDto.class));
result.setDatas(userDtos);
result.setSuccess(true);
return result;
}catch(Exception e){
e.printStackTrace();
result.setSuccess(false);
result.setMessage("用户名或密码错误!");
System.out.println("用户名或密码错误!");
return result;
} } /**
* 获得当前用户id
* @return
*/
public String currentUserId() {
Subject subject = SecurityUtils.getSubject();
PrincipalCollection collection = subject.getPrincipals();
if (null != collection && !collection.isEmpty()) {
String userName = (String) collection.iterator().next();
return userDao.findOneByUserName(userName).getId();
}
return null;
} /**
* 踢除用户
* http://www.ithao123.cn/content-7174367.html
*/
public void kickOutUser(UsernamePasswordToken token){
String loginName = token.getUsername();
Collection<Session> sessions = sessionDAO.getActiveSessions();
for(Session session:sessions){
if(loginName.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)))) {
//设置session立即失效,即将其踢出系统
session.setTimeout(0);
}
}
} /**
* 退出登录
*/
public void logout() {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
// session 会销毁,在SessionListener监听session销毁,清理权限缓存
subject.logout();
}
} /**
* 获取当前用户名
* @return
*/
public Result getOneUserName() {
Subject subject = SecurityUtils.getSubject();
PrincipalCollection collection = subject.getPrincipals();
Result result = new Result();
if (null != collection && !collection.isEmpty()) {
String userName = (String) collection.iterator().next();
result.setSuccess(true);
List<String> datas = new ArrayList<String>();
datas.add(userName);
result.setDatas(datas);
return result;
}
result.setSuccess(false);
return result;
} /**
* 修改用户信息
* @param userId
* @param userDto
* @return
*/
public Result updateUserDetails(String userId, UserDto userDto) {
Result result = new Result();
User user = modelMapper.map(userDto, User.class);
user.setId(userId);
user.setPassword(userDao.findOne(userId).getPassword());
user.setCreateTime(userDao.findOne(userId).getCreateTime());
user.setRole(userDao.findOne(userId).getRole());
if (!userDto.getUserName().equals(userDao.findOne(userId).getUserName())) {
result.setMessage("修改成功,立即重新登录!");
} else {
result.setMessage("修改成功!");
}
userDao.save(user);
result.setId(userId);
result.setSuccess(true);
return result;
} }
需要注意,前端需要编写全局ajax以便对用户友好提示权限相关信息,
统一处理页面登录超时和无权限情况(一般在每一个页面都会调用的js文件中编写以便覆盖完整)
//统一处理页面登录超时和无权限情况
jQuery(function($){
// 备份jquery的ajax方法
var _ajax = $.ajax;
// 重写ajax方法
$.ajax=function(opt){
var _error = opt && opt.error || function(a, b){};
var _opt = $.extend(opt, {
error:function(data, textStatus){
// 如果后台将请求重定向到了登录页,则data里面存放的就是登录页的源码,这里需要找到data是登录页的证据(标记)
if(data.responseText.indexOf("无此权限") > 0) {
alert("无此权限");
return;
} else if (data.responseText.indexOf("请输入用户名") > 0) {
alert("登录超时,请重新登录!");
window.location.href = '/views/login.html';
return;
} else {
alert("error");
return;
}
_error(data, textStatus);
}
});
_ajax(_opt);
};
});
data.responseText获取得到的是applicationContext-shiro.xml里的配置
登录超时:
<property name="loginUrl" value="/views/login.html"/>
无权限:
<property name="unauthorizedUrl" value="/unauthorized.html"/>
对应页面的html的代码
shiro+spring相关配置的更多相关文章
- Spring学习笔记(二)——Spring相关配置&属性注入&Junit整合
一.Spring的相关配置 1.1 Bean元素 class属性:被管理对象的完整类名 name属性:给Bean起个名字,能重复,能使用特殊字符.后来属性 id属性:给Bean起个名字,不能重复,不能 ...
- spring关于“transactionAttributes”的相关配置
spring关于"transactionAttributes"的相关配置 <bean id="baseTransactionProxy" class=&q ...
- shiro开发,shiro的环境配置(基于spring+springMVC+redis)
特别感谢lhacker分享的文章,对我帮助很大 http://www.aiuxian.com/article/p-1913280.html 基本的知识就不在这里讲了,在实战中体会shiro的整体设计理 ...
- 转-spring boot web相关配置
spring boot web相关配置 80436 spring boot集成了servlet容器,当我们在pom文件中增加spring-boot-starter-web的maven依赖时,不做任何w ...
- spring mvc 图片上传,图片压缩、跨域解决、 按天生成文件夹 ,删除,限制为图片代码等相关配置
spring mvc 图片上传,跨域解决 按天生成文件夹 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ ...
- spring下配置shiro
1.web.xml中加入shiro的过滤器: <!-- Spring --> <!-- 配置Spring配置文件路径 --> <context-param> < ...
- shiro配置参考(二)可以和mybatis的配置放在一个文件中(不建议这样,可以拆分开来,注意相关配置即可)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 【spring boot logback】日志使用自定义的logback-spring.xml文件后,application.properties中关于日志的相关配置还会起作用么
本篇 将针对[日志使用自定义的logback-spring.xml文件后,application.properties中关于日志的相关配置还会起作用么]这一个主题进行探索. 这个测试项目是根据[spr ...
- Spring Bean相关配置
Bean相关配置 1.名称与标识 id 使用了约束中的唯一约束.里面不能出现特殊字符的 name 没有使用约束中的唯一约束.里面可以出现特殊字符. 设置对象的生命周期方法 init-method Be ...
随机推荐
- Multiple Regression
Multiple Regression What is multiple regression? Multiple regression is regression analysis with mor ...
- Java项目(5)——单例模式的应用与研究
单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常easy,非常特别,作用就是保证一个类有唯一一个实例,并让一个全局变量使得它能被訪问.而保证这个类仅仅被实例化一次的办法就 ...
- HTTP请求中的Keep-Alive模式详解
Keep-Alive模式 我们都知道HTTP是基于TCP的,每一个HTTP请求都需要进行三步握手.如果一个页面对某一个域名有多个请求,就会进行频繁的建立连接和断开连接.所以HTTP 1.0中出现了Co ...
- ny37 回文字符串
回文字符串 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当 ...
- HBase性能优化方法总结(二):写表操作
转自:http://www.cnblogs.com/panfeng412/archive/2012/03/08/hbase-performance-tuning-section2.html 本文主要是 ...
- ubuntu 12.04下gedit查看txt中文乱码解决办法
http://blog.sina.com.cn/s/blog_6273990801013dwv.html 由于我不能要求别人保存txt文件时必须用utf-8,那我只能自己找解决办法: 打开终端输入: ...
- AIX逻辑卷扩展空间
aix磁盘系统 a.基本概念: PV 物理卷:普通的直接访问的存储设备,有固定的和可移动的之分,代表性的就是硬盘. vg 卷组:AIX中最大的存储单位,一个卷组由一组物理硬盘组成,也就是由一个或多个物 ...
- [转]好用工具:Oracle SQL Developer
我們一直以來就很少使用 Oracle 資料庫,一年下來也頂多 1 ~ 2 個案子採用 Oracle 的資料庫,所以一直都對 Oracle 資料庫的操作不太熟悉,尤其是用 Oracle 內建的那些超難用 ...
- 推荐一款编辑SQL的工具:jsqlparser
这个工具真的挺好用的,采用的是观察者模式,Visitor. 虽然我学过这个模式,但是乍一用还是有点懵逼的. 给好一个SQL语句之后,jsqlparser可以把这个sql语句给分解成all kind o ...
- UTF-8以字节为单位对Unicode进行编码
UTF-8以字节为单位对Unicode进行编码.从Unicode到UTF-8的编码方式如下: Unicode编码(16进制) UTF-8 字节流(二进制) 000000 - 00007F 0xxxxx ...