最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 集成Shiro的多realm配置過程

 更新時間:2020年10月20日 08:45:58   作者:c.  
這篇文章主要介紹了Spring Boot 集成Shiro的多realm配置,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

我在做畢設(shè)的時候采用shiro進行登錄認證和權(quán)限管理的實現(xiàn)。其中需求涉及使用三個角色分別是:學生、教師、管理員。現(xiàn)在要三者實現(xiàn)分開登錄。即需要三個Realm——StudentRealm和TeacherRealm、AdminRealm,分別處理學生、教師和管理員的驗證功能。

但是正常情況下,當定義了多個Realm,無論是學生登錄,教師登錄,還是管理員登錄,都會由這三個Realm共同處理。這是因為,當配置了多個Realm時,我們通常使用的認證器是shiro自帶的org.apache.shiro.authc.pam.ModularRealmAuthenticator,其中決定使用的Realm的是doAuthenticate()方法,源代碼如下:

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
  assertRealmsConfigured();
  Collection<Realm> realms = getRealms();
  if (realms.size() == 1) {
   return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
  } else {
   return doMultiRealmAuthentication(realms, authenticationToken);
  }
 }

上述代碼的意思就是如果有多個Realm就會使用所有配置的Realm。 只有一個的時候,就直接使用當前的Realm。

為了實現(xiàn)需求,我會創(chuàng)建一個org.apache.shiro.authc.pam.ModularRealmAuthenticator的子類,并重寫doAuthenticate()方法,讓特定的Realm完成特定的功能。如何區(qū)分呢?我會同時創(chuàng)建一個org.apache.shiro.authc.UsernamePasswordToken的子類,在其中添加一個字段loginType,用來標識登錄的類型,即是學生登錄、教師登錄,還是管理員登錄。具體步驟如下(我的代碼使用的是Groovy):

enum LoginType {
 STUDENT("Student"), ADMIN("Admin"), TEACHER("Teacher")

 private String type

 private LoginType(String type) {
  this.type = type
 }

 @Override
 public String toString() {
  return this.type.toString()
 }
}

接下來新建org.apache.shiro.authc.UsernamePasswordToken的子類UserToken

import org.apache.shiro.authc.UsernamePasswordToken

class UserToken extends UsernamePasswordToken {

 //登錄類型,判斷是學生登錄,教師登錄還是管理員登錄
 private String loginType

 public UserToken(final String username, final String password,String loginType) {
  super(username,password)
  this.loginType = loginType
 }

 public String getLoginType() {
  return loginType
 }
 public void setLoginType(String loginType) {
  this.loginType = loginType
 }
}

第三步:新建org.apache.shiro.authc.pam.ModularRealmAuthenticator的子類UserModularRealmAuthenticator:

import org.apache.shiro.authc.AuthenticationException
import org.apache.shiro.authc.AuthenticationInfo
import org.apache.shiro.authc.AuthenticationToken
import org.apache.shiro.authc.pam.ModularRealmAuthenticator
import org.apache.shiro.realm.Realm
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * 當配置了多個Realm時,我們通常使用的認證器是shiro自帶的org.apache.shiro.authc.pam.ModularRealmAuthenticator,其中決定使用的Realm的是doAuthenticate()方法
 *
 * 自定義Authenticator
 * 注意,當需要分別定義處理學生和教師和管理員驗證的Realm時,對應(yīng)Realm的全類名應(yīng)該包含字符串“Student”“Teacher”,或者“Admin”。
 * 并且,他們不能相互包含,例如,處理學生驗證的Realm的全類名中不應(yīng)該包含字符串"Admin"。
 */
class UserModularRealmAuthenticator extends ModularRealmAuthenticator {

 private static final Logger logger = LoggerFactory.getLogger(UserModularRealmAuthenticator.class)

 @Override
 protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
   throws AuthenticationException {
  logger.info("UserModularRealmAuthenticator:method doAuthenticate() execute ")
  // 判斷getRealms()是否返回為空
  assertRealmsConfigured()
  // 強制轉(zhuǎn)換回自定義的CustomizedToken
  UserToken userToken = (UserToken) authenticationToken
  // 登錄類型
  String loginType = userToken?.getLoginType()
  // 所有Realm
  Collection<Realm> realms = getRealms()
  // 登錄類型對應(yīng)的所有Realm
  Collection<Realm> typeRealms = new ArrayList<>()
  for (Realm realm : realms) {
   if (realm?.getName()?.contains(loginType))
    typeRealms?.add(realm)
  }

  // 判斷是單Realm還是多Realm
  if (typeRealms?.size() == 1){
   logger.info("doSingleRealmAuthentication() execute ")
   return doSingleRealmAuthentication(typeRealms?.get(0), userToken)
  }
  else{
   logger.info("doMultiRealmAuthentication() execute ")
   return doMultiRealmAuthentication(typeRealms, userToken)
  }
 }
}

第四步:創(chuàng)建分別處理學生登錄和教師登錄、管理員登錄的Realm:
我這里直接貼出了我項目中的代碼,你們可以根據(jù)具體的需求進行操作。
AdminShiroRealm :

package com.ciyou.edu.config.shiro.admin
import com.ciyou.edu.config.shiro.common.UserToken
import com.ciyou.edu.entity.Admin
import com.ciyou.edu.service.AdminService
import com.ciyou.edu.service.PermissionService
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.authc.UnknownAccountException
import org.apache.shiro.authz.AuthorizationException
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.apache.shiro.util.ByteSource
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy


class AdminShiroRealm extends AuthorizingRealm {

  private static final Logger logger = LoggerFactory.getLogger(AdminShiroRealm.class)
  @Autowired
  @Lazy
  private AdminService adminService


 @Autowired
 @Lazy
 private PermissionService permissionService



 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

  logger.info("開始Admin身份認證...")
  UserToken userToken = (UserToken)token
  String adminName = userToken?.getUsername() //獲取用戶名,默認和login.html中的adminName對應(yīng)。
  Admin admin = adminService?.findByAdminName(adminName)

  if (admin == null) {
   //沒有返回登錄用戶名對應(yīng)的SimpleAuthenticationInfo對象時,就會在LoginController中拋出UnknownAccountException異常
   throw new UnknownAccountException("用戶不存在!")
  }

  //驗證通過返回一個封裝了用戶信息的AuthenticationInfo實例即可。
  SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
    admin, //用戶信息
    admin?.getPassword(), //密碼
    getName() //realm name
  )
  authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(admin?.getAdminName())) //設(shè)置鹽
  logger.info("返回Admin認證信息:" + authenticationInfo)
  return authenticationInfo
 }

//當訪問到頁面的時候,鏈接配置了相應(yīng)的權(quán)限或者shiro標簽才會執(zhí)行此方法否則不會執(zhí)行
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

  logger.info("開始Admin權(quán)限授權(quán)(進行權(quán)限驗證!!)")
  if (principals == null) {
   throw new AuthorizationException("PrincipalCollection method argument cannot be null.")
  }
  SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo()
  if(principals?.getPrimaryPrincipal() instanceof Admin){
   Admin admin = (Admin) principals?.getPrimaryPrincipal()
   logger.info("當前Admin :" + admin )
   authorizationInfo?.addRole("Admin")
   //每次都從數(shù)據(jù)庫重新查找,確保能及時更新權(quán)限
   admin?.setPermissionList(permissionService?.findPermissionByAdmin(admin?.getAdminId()))
   admin?.getPermissionList()?.each {current_Permission ->
    authorizationInfo?.addStringPermission(current_Permission?.getPermission())
   }
   logger.info("當前Admin授權(quán)角色:" +authorizationInfo?.getRoles() + ",權(quán)限:" + authorizationInfo?.getStringPermissions())
   return authorizationInfo
  }
 }
}

TeacherShiroRealm :

package com.ciyou.edu.config.shiro.teacher

import com.ciyou.edu.config.shiro.common.UserToken
import com.ciyou.edu.entity.Teacher
import com.ciyou.edu.service.TeacherService
import org.apache.shiro.authc.*
import org.apache.shiro.authz.AuthorizationException
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.apache.shiro.util.ByteSource
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy


class TeacherShiroRealm extends AuthorizingRealm {
 private static final Logger logger = LoggerFactory.getLogger(TeacherShiroRealm.class)

 //在自定義Realm中注入的Service聲明中加入@Lazy注解即可解決@cacheble注解無效問題
 //解決同時使用Redis緩存數(shù)據(jù)和緩存shiro時,@cacheble無效的問題
  @Autowired
  @Lazy
  private TeacherService teacherService



 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

  logger.info("開始Teacher身份認證..")
  UserToken userToken = (UserToken)token
  String teacherId = userToken?.getUsername()
  Teacher teacher = teacherService?.findByTeacherId(teacherId)

  if (teacher == null) {
   //沒有返回登錄用戶名對應(yīng)的SimpleAuthenticationInfo對象時,就會在LoginController中拋出UnknownAccountException異常
   throw new UnknownAccountException("用戶不存在!")
  }

  //驗證通過返回一個封裝了用戶信息的AuthenticationInfo實例即可。
  SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
    teacher, //用戶信息
    teacher?.getPassword(), //密碼
    getName() //realm name
  )
  authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(teacher?.getTeacherId())) //設(shè)置鹽

  return authenticationInfo
 }

//當訪問到頁面的時候,鏈接配置了相應(yīng)的權(quán)限或者shiro標簽才會執(zhí)行此方法否則不會執(zhí)行
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  logger.info("開始Teacher權(quán)限授權(quán)")
  if (principals == null) {
   throw new AuthorizationException("PrincipalCollection method argument cannot be null.")
  }
  SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo()
  if(principals?.getPrimaryPrincipal() instanceof Teacher){
   authorizationInfo?.addRole("Teacher")
   return authorizationInfo
  }
 }
}

StudentShiroRealm :

package com.ciyou.edu.config.shiro.student

import com.ciyou.edu.config.shiro.common.UserToken
import com.ciyou.edu.entity.Student
import com.ciyou.edu.service.StudentService
import org.apache.shiro.authc.*
import org.apache.shiro.authz.AuthorizationException
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.apache.shiro.util.ByteSource
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy


class StudentShiroRealm extends AuthorizingRealm {
 private static final Logger logger = LoggerFactory.getLogger(StudentShiroRealm.class)

 //在自定義Realm中注入的Service聲明中加入@Lazy注解即可解決@cacheble注解無效問題
 //解決同時使用Redis緩存數(shù)據(jù)和緩存shiro時,@cacheble無效的問題
  @Autowired
  @Lazy
  private StudentService studentService



 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

  logger.info("開始Student身份認證..")
  UserToken userToken = (UserToken)token
  String studentId = userToken?.getUsername()
  Student student = studentService?.findByStudentId(studentId)

  if (student == null) {
   //沒有返回登錄用戶名對應(yīng)的SimpleAuthenticationInfo對象時,就會在LoginController中拋出UnknownAccountException異常
   throw new UnknownAccountException("用戶不存在!")
  }

  //驗證通過返回一個封裝了用戶信息的AuthenticationInfo實例即可。
  SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
    student, //用戶信息
    student?.getPassword(), //密碼
    getName() //realm name
  )
  authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(student?.getStudentId())) //設(shè)置鹽

  return authenticationInfo
 }

//當訪問到頁面的時候,鏈接配置了相應(yīng)的權(quán)限或者shiro標簽才會執(zhí)行此方法否則不會執(zhí)行
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  logger.info("開始Student權(quán)限授權(quán)")
  if (principals == null) {
   throw new AuthorizationException("PrincipalCollection method argument cannot be null.")
  }
  SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo()
  if(principals?.getPrimaryPrincipal() instanceof Student){
   authorizationInfo?.addRole("Student")
   return authorizationInfo
  }
 }
}

接下來是對Shiro進行多realm的注解配置。
這里直接貼出我項目中的代碼。

 

上面是我進行shiro進行配置的類,下面是主要的一些代碼:

//SecurityManager 是 Shiro 架構(gòu)的核心,通過它來鏈接Realm和用戶(文檔中稱之為Subject.)
 @Bean
 public SecurityManager securityManager() {
  DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager()
  //設(shè)置realm.
  securityManager.setAuthenticator(modularRealmAuthenticator())
  List<Realm> realms = new ArrayList<>()
  //添加多個Realm
  realms.add(adminShiroRealm())
  realms.add(teacherShiroRealm())
  realms.add(studentShiroRealm())
  securityManager.setRealms(realms)
  // 自定義緩存實現(xiàn) 使用redis
  securityManager.setCacheManager(cacheManager())
  // 自定義session管理 使用redis
  securityManager.setSessionManager(sessionManager())
  //注入記住我管理器;
  securityManager.setRememberMeManager(rememberMeManager())
  return securityManager
 }

 /**
  * 系統(tǒng)自帶的Realm管理,主要針對多realm
  * */
 @Bean
 public ModularRealmAuthenticator modularRealmAuthenticator(){
  //自己重寫的ModularRealmAuthenticator
  UserModularRealmAuthenticator modularRealmAuthenticator = new UserModularRealmAuthenticator()
  modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy())
  return modularRealmAuthenticator
 }

 @Bean
 public AdminShiroRealm adminShiroRealm() {
  AdminShiroRealm adminShiroRealm = new AdminShiroRealm()
  adminShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher())//設(shè)置解密規(guī)則
  return adminShiroRealm
 }

 @Bean
 public StudentShiroRealm studentShiroRealm() {
  StudentShiroRealm studentShiroRealm = new StudentShiroRealm()
  studentShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher())//設(shè)置解密規(guī)則
  return studentShiroRealm
 }

 @Bean
 public TeacherShiroRealm teacherShiroRealm() {
  TeacherShiroRealm teacherShiroRealm = new TeacherShiroRealm()
  teacherShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher())//設(shè)置解密規(guī)則
  return teacherShiroRealm
 }

 //因為我們的密碼是加過密的,所以,如果要Shiro驗證用戶身份的話,需要告訴它我們用的是md5加密的,并且是加密了兩次。同時我們在自己的Realm中也通過SimpleAuthenticationInfo返回了加密時使用的鹽。這樣Shiro就能順利的解密密碼并驗證用戶名和密碼是否正確了。
 @Bean
 public HashedCredentialsMatcher hashedCredentialsMatcher() {
  HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher()
  hashedCredentialsMatcher.setHashAlgorithmName("md5")//散列算法:這里使用MD5算法;
  hashedCredentialsMatcher.setHashIterations(2)//散列的次數(shù),比如散列兩次,相當于 md5(md5(""));
  return hashedCredentialsMatcher;
 }

接下來就是Controller中實現(xiàn)登錄的功能了,這里我只貼出我項目中Admin登錄的代碼:

package com.ciyou.edu.controller.admin

import com.ciyou.edu.config.shiro.common.LoginType
import com.ciyou.edu.config.shiro.common.UserToken
import com.ciyou.edu.entity.Admin
import com.ciyou.edu.utils.JSONUtil
import org.apache.shiro.SecurityUtils
import org.apache.shiro.authc.AuthenticationException
import org.apache.shiro.subject.Subject
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.ResponseBody


/**
 * @Author C.
 * @Date 2018-02-02 20:46
 * admin登錄Controller
 */
@Controller
class AdminLoginController {

 private static final Logger logger = LoggerFactory.getLogger(AdminLoginController.class)
 private static final String ADMIN_LOGIN_TYPE = LoginType.ADMIN.toString()

 /**
  * admin登錄
  * @param admin
  * @return 登錄結(jié)果
  */
 @RequestMapping(value="/adminLogin",method=RequestMethod.POST, produces="application/json;charset=UTF-8")
 @ResponseBody
 public String loginAdmin(Admin admin){
  logger.info("登錄Admin: " + admin)
  //后臺校驗提交的用戶名和密碼
  if(!admin?.getAdminName() || admin?.adminName?.trim() == ""){
   return JSONUtil.returnFailReuslt("賬號不能為空")
  }else if(!admin?.getPassword() || admin?.getPassword()?.trim() == ""){
   return JSONUtil.returnFailReuslt("密碼不能為空")
  }else if(admin?.getAdminName()?.length() < 3 || admin?.getAdminName()?.length() >15){
   return JSONUtil.returnFailReuslt("賬號長度必須在3~15之間")
  }else if(admin?.getPassword()?.length() < 3 || admin?.getPassword()?.length() >15){
   return JSONUtil.returnFailReuslt("密碼長度必須在3~15之間")
  }

  //獲取Subject實例對象
  //在shiro里面所有的用戶的會話信息都會由Shiro來進行控制,那么也就是說只要是與用戶有關(guān)的一切的處理信息操作都可以通過Shiro取得,
  // 實際上可以取得的信息可以有用戶名、主機名稱等等,這所有的信息都可以通過Subject接口取得
  Subject subject = SecurityUtils.getSubject()

  //將用戶名和密碼封裝到繼承了UsernamePasswordToken的userToken
  UserToken userToken = new UserToken(admin?.getAdminName(), admin?.getPassword(), ADMIN_LOGIN_TYPE)
  userToken.setRememberMe(false)
  try {
   //認證
   // 傳到ModularRealmAuthenticator類中,然后根據(jù)ADMIN_LOGIN_TYPE傳到AdminShiroRealm的方法進行認證
   subject?.login(userToken)
   //Admin存入session
   SecurityUtils.getSubject()?.getSession()?.setAttribute("admin",(Admin)subject?.getPrincipal())
   return JSONUtil.returnSuccessResult("登錄成功")
  } catch (AuthenticationException e) {
   //認證失敗就會拋出AuthenticationException這個異常,就對異常進行相應(yīng)的操作,這里的處理是拋出一個自定義異常ResultException
   //到時候我們拋出自定義異常ResultException,用戶名或者密碼錯誤
   logger.info("認證錯誤:" + e.getMessage())
   return JSONUtil.returnFailReuslt("賬號或者密碼錯誤")
  }
 }

 @RequestMapping(value="/admin/adminLogout")
 public String logoutAdmin(){
  SecurityUtils.getSubject()?.logout()
  return "redirect:/adminLogin"
 }
}

現(xiàn)在Spring Boot中集成Shiro實現(xiàn)多realm配置就完成了。

感謝以下博文,在我學習的過程中給了我很多幫助,我的博文也有一些內(nèi)容參考他們的,還不夠清楚的讀者可以參考:
shiro實現(xiàn)不同身份使用不同Realm進行驗證
SpringBoot+Shiro學習之數(shù)據(jù)庫動態(tài)權(quán)限管理和Redis緩存
Springboot多realm集成,無ini文件,無xml配置

想看項目具體源碼,或者對我項目感興趣的可以查看:CIYOU

到此這篇關(guān)于Spring Boot 集成Shiro的多realm配置過程的文章就介紹到這了,更多相關(guān)Spring Boot多realm配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題

    解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題

    這篇文章主要介紹了解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的方法、常量、變量、參數(shù)用例詳解

    Java中的方法、常量、變量、參數(shù)用例詳解

    在JVM的運轉(zhuǎn)中,承載的是數(shù)據(jù),而數(shù)據(jù)的一種變現(xiàn)形式就是“量”,量分為:常量與變量,我們在數(shù)學和物理學中已經(jīng)接觸過變量的概念了,在Java中的變量就是在程序運行過程中可以改變其值的量,這篇文章主要介紹了Java中的方法、常量、變量、參數(shù),需要的朋友可以參考下
    2024-01-01
  • Spring實現(xiàn)文件上傳的配置詳解

    Spring實現(xiàn)文件上傳的配置詳解

    這篇文章將為大家詳細說明一下spring上傳文件如何配置,以及從request請求中解析到文件流的原理,文中示例代碼講解詳細,感興趣的可以了解一下
    2022-08-08
  • java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解

    java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解

    這篇文章主要介紹了java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 使用idea啟動DataX的方法示例

    使用idea啟動DataX的方法示例

    這篇文章主要介紹了使用idea啟動DataX的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Spring如何按業(yè)務(wù)模塊輸出日志到不同的文件詳解

    Spring如何按業(yè)務(wù)模塊輸出日志到不同的文件詳解

    最近做項目時有一個記錄操作日志的需求,比如某個用戶進行了查詢、刪除、修改等操作,下面這篇文章主要給大家介紹了關(guān)于Spring如何按業(yè)務(wù)模塊輸出日志到不同文件的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • 使用Digester解析XML文件的三種方式小結(jié)

    使用Digester解析XML文件的三種方式小結(jié)

    Digester是apache開源項目Commons中的一個子項目,用于解析XML文檔的工具,本文為大家整理了Digester解析XML文件的三種方式,希望對大家有所幫助
    2024-01-01
  • 解決Java?properties文件里面如何寫"\"的問題

    解決Java?properties文件里面如何寫"\"的問題

    由于properties使用“\”相當于是java的轉(zhuǎn)義符,如果想要寫出\的效果,只需修改相應(yīng)的寫法即可,對java?properties文件里的"\"寫法感興趣的朋友一起看看吧
    2022-04-04
  • 分析java 中AspectJ切面執(zhí)行兩次的原因

    分析java 中AspectJ切面執(zhí)行兩次的原因

    這篇文章主要介紹了分析java 中AspectJ切面執(zhí)行兩次的原因的相關(guān)資料,希望通過本能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • JavaMail整合Spring實現(xiàn)郵件發(fā)送功能

    JavaMail整合Spring實現(xiàn)郵件發(fā)送功能

    這篇文章主要為大家詳細介紹了JavaMail整合Spring實現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評論

北辰区| 长垣县| 新和县| 蚌埠市| 康乐县| 洪泽县| 贺兰县| 扎兰屯市| 柞水县| 龙岩市| 龙州县| 林芝县| 高雄市| 临洮县| 连山| 邢台市| 固阳县| 鹰潭市| 巢湖市| 金门县| 黄浦区| 调兵山市| 南京市| 罗平县| 汉寿县| 古田县| 灯塔市| 昌吉市| 邵阳市| 温州市| 彭阳县| 武义县| 全州县| 彰武县| 贵溪市| 平昌县| 长海县| 贡觉县| 黄浦区| 大足县| 壶关县|