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

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

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

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

但是正常情況下,當(dāng)定義了多個(gè)Realm,無(wú)論是學(xué)生登錄,教師登錄,還是管理員登錄,都會(huì)由這三個(gè)Realm共同處理。這是因?yàn)?,?dāng)配置了多個(gè)Realm時(shí),我們通常使用的認(rèn)證器是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);
  }
 }

上述代碼的意思就是如果有多個(gè)Realm就會(huì)使用所有配置的Realm。 只有一個(gè)的時(shí)候,就直接使用當(dāng)前的Realm。

為了實(shí)現(xiàn)需求,我會(huì)創(chuàng)建一個(gè)org.apache.shiro.authc.pam.ModularRealmAuthenticator的子類,并重寫doAuthenticate()方法,讓特定的Realm完成特定的功能。如何區(qū)分呢?我會(huì)同時(shí)創(chuàng)建一個(gè)org.apache.shiro.authc.UsernamePasswordToken的子類,在其中添加一個(gè)字段loginType,用來(lái)標(biāo)識(shí)登錄的類型,即是學(xué)生登錄、教師登錄,還是管理員登錄。具體步驟如下(我的代碼使用的是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()
 }
}

接下來(lái)新建org.apache.shiro.authc.UsernamePasswordToken的子類UserToken

import org.apache.shiro.authc.UsernamePasswordToken

class UserToken extends UsernamePasswordToken {

 //登錄類型,判斷是學(xué)生登錄,教師登錄還是管理員登錄
 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

/**
 * 當(dāng)配置了多個(gè)Realm時(shí),我們通常使用的認(rèn)證器是shiro自帶的org.apache.shiro.authc.pam.ModularRealmAuthenticator,其中決定使用的Realm的是doAuthenticate()方法
 *
 * 自定義Authenticator
 * 注意,當(dāng)需要分別定義處理學(xué)生和教師和管理員驗(yàn)證的Realm時(shí),對(duì)應(yīng)Realm的全類名應(yīng)該包含字符串“Student”“Teacher”,或者“Admin”。
 * 并且,他們不能相互包含,例如,處理學(xué)生驗(yàn)證的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()
  // 強(qiáng)制轉(zhuǎn)換回自定義的CustomizedToken
  UserToken userToken = (UserToken) authenticationToken
  // 登錄類型
  String loginType = userToken?.getLoginType()
  // 所有Realm
  Collection<Realm> realms = getRealms()
  // 登錄類型對(duì)應(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)建分別處理學(xué)生登錄和教師登錄、管理員登錄的Realm:
我這里直接貼出了我項(xiàng)目中的代碼,你們可以根據(jù)具體的需求進(jìn)行操作。
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身份認(rèn)證...")
  UserToken userToken = (UserToken)token
  String adminName = userToken?.getUsername() //獲取用戶名,默認(rèn)和login.html中的adminName對(duì)應(yīng)。
  Admin admin = adminService?.findByAdminName(adminName)

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

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

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

  logger.info("開始Admin權(quán)限授權(quán)(進(jìn)行權(quán)限驗(yà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("當(dāng)前Admin :" + admin )
   authorizationInfo?.addRole("Admin")
   //每次都從數(shù)據(jù)庫(kù)重新查找,確保能及時(shí)更新權(quán)限
   admin?.setPermissionList(permissionService?.findPermissionByAdmin(admin?.getAdminId()))
   admin?.getPermissionList()?.each {current_Permission ->
    authorizationInfo?.addStringPermission(current_Permission?.getPermission())
   }
   logger.info("當(dāng)前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注解無(wú)效問題
 //解決同時(shí)使用Redis緩存數(shù)據(jù)和緩存shiro時(shí),@cacheble無(wú)效的問題
  @Autowired
  @Lazy
  private TeacherService teacherService



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

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

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

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

  return authenticationInfo
 }

//當(dāng)訪問到頁(yè)面的時(shí)候,鏈接配置了相應(yīng)的權(quán)限或者shiro標(biāo)簽才會(huì)執(zhí)行此方法否則不會(huì)執(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注解無(wú)效問題
 //解決同時(shí)使用Redis緩存數(shù)據(jù)和緩存shiro時(shí),@cacheble無(wú)效的問題
  @Autowired
  @Lazy
  private StudentService studentService



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

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

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

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

  return authenticationInfo
 }

//當(dāng)訪問到頁(yè)面的時(shí)候,鏈接配置了相應(yīng)的權(quán)限或者shiro標(biāo)簽才會(huì)執(zhí)行此方法否則不會(huì)執(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
  }
 }
}

接下來(lái)是對(duì)Shiro進(jìn)行多realm的注解配置。
這里直接貼出我項(xiàng)目中的代碼。

 

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

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

 /**
  * 系統(tǒng)自帶的Realm管理,主要針對(duì)多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
 }

 //因?yàn)槲覀兊拿艽a是加過密的,所以,如果要Shiro驗(yàn)證用戶身份的話,需要告訴它我們用的是md5加密的,并且是加密了兩次。同時(shí)我們?cè)谧约旱腞ealm中也通過SimpleAuthenticationInfo返回了加密時(shí)使用的鹽。這樣Shiro就能順利的解密密碼并驗(yàn)證用戶名和密碼是否正確了。
 @Bean
 public HashedCredentialsMatcher hashedCredentialsMatcher() {
  HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher()
  hashedCredentialsMatcher.setHashAlgorithmName("md5")//散列算法:這里使用MD5算法;
  hashedCredentialsMatcher.setHashIterations(2)//散列的次數(shù),比如散列兩次,相當(dāng)于 md5(md5(""));
  return hashedCredentialsMatcher;
 }

接下來(lái)就是Controller中實(shí)現(xiàn)登錄的功能了,這里我只貼出我項(xiàng)目中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)
  //后臺(tái)校驗(yàn)提交的用戶名和密碼
  if(!admin?.getAdminName() || admin?.adminName?.trim() == ""){
   return JSONUtil.returnFailReuslt("賬號(hào)不能為空")
  }else if(!admin?.getPassword() || admin?.getPassword()?.trim() == ""){
   return JSONUtil.returnFailReuslt("密碼不能為空")
  }else if(admin?.getAdminName()?.length() < 3 || admin?.getAdminName()?.length() >15){
   return JSONUtil.returnFailReuslt("賬號(hào)長(zhǎng)度必須在3~15之間")
  }else if(admin?.getPassword()?.length() < 3 || admin?.getPassword()?.length() >15){
   return JSONUtil.returnFailReuslt("密碼長(zhǎng)度必須在3~15之間")
  }

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

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

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

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

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

想看項(xiàng)目具體源碼,或者對(duì)我項(xiàng)目感興趣的可以查看:CIYOU

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    使用idea啟動(dòng)DataX的方法示例

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

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

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

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

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

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

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

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

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

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

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

最新評(píng)論

五原县| 冕宁县| 健康| 兴安县| 勐海县| 江北区| 澜沧| 女性| 临潭县| 兴仁县| 东乡| 甘德县| 轮台县| 治多县| 武宣县| 鱼台县| 深圳市| 缙云县| 峨山| 湛江市| 乌拉特前旗| 广饶县| 霍城县| 莱芜市| 乐都县| 衢州市| 万山特区| 新蔡县| 纳雍县| 霍州市| 无为县| 申扎县| 容城县| 苍南县| 京山县| 隆林| 崇明县| 马鞍山市| 镇康县| 三台县| 会同县|