技术标签: spring boot 框架、工具学习笔记 java shiro
笔记根据视频以及自己操作整理
视频地址:https://www.bilibili.com/video/BV1PE411i7CV?p=38
1.1 什么是Shiro?
1.3 外部结构
1.4 内部结构
github地址:https://github.com/apache/shiro.
1、 创建新的maven项目
2、引入依赖
再去maven仓库中找到版本号
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
<!-- configure logging -->
<!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.0-alpha1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
3、复制quickstart项目
resources目录下:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
# General Apache libraries
log4j.logger.org.apache=WARN
# Spring
log4j.logger.org.springframework=WARN
# Default Shiro logging
log4j.logger.org.apache.shiro=INFO
# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContext=WARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz
# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5
java目录下:QuickStart.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.ini.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.lang.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple Quickstart application showing how to use Shiro's API.
*
* @since 0.9 RC2
*/
public class Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
// The easiest way to create a Shiro SecurityManager with configured
// realms, users, roles and permissions is to use the simple INI config.
// We'll do that by using a factory that can ingest a .ini file and
// return a SecurityManager instance:
// Use the shiro.ini file at the root of the classpath
// (file: and url: prefixes load from files and urls respectively):
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
// for this simple example quickstart, make the SecurityManager
// accessible as a JVM singleton. Most applications wouldn't do this
// and instead rely on their container configuration or web.xml for
// webapps. That is outside the scope of this simple quickstart, so
// we'll just do the bare minimum so you can continue to get a feel
// for things.
SecurityUtils.setSecurityManager(securityManager);
// Now that a simple Shiro environment is set up, let's see what you can do:
// get the currently executing user:
Subject currentUser = SecurityUtils.getSubject();
// Do some stuff with a Session (no need for a web or EJB container!!!)
Session session = currentUser.getSession();
session.setAttribute("someKey", "aValue");
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
}
// let's login the current user so we can check against roles and permissions:
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (UnknownAccountException uae) {
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
}
// ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {
//unexpected condition? error?
}
}
//say who they are:
//print their identifying principal (in this case, a username):
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
//test a role:
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//test a typed permission (not instance-level)
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//a (very powerful) Instance Level permission:
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
//all done - log out!
currentUser.logout();
System.exit(0);
}
}
4、测试结果
1、搭建环境
1、创建springboot项目
新建测试页面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http:www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<p th:text="${msg}"></p>
</body>
</html>
新建controller
@Controller
public class MyController {
@GetMapping({
"/","/index"})
public String toIndex(Model model){
model.addAttribute("msg", "hello shiro");
return "index";
}
}
测试成功。
2、整合springboot
1、引入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.1</version>
</dependency>
2、编写自定义Realm
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
return null;
}
}
3、编写ShiroConfig
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean:3
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
return bean;
}
//DefaultWebSecurityManager:2
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象, 需要自定义
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
4、创建测试页面:
ShiroConfig.java
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean:3
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加Shiro的内置过滤器
/*anon: 无需认证就可以访问
* authc: 必须认证了才能访问
* user:必须拥有 记住我 功能才能访问
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色权限才能访问
* */
LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
//filterMap.put("/user/add", "authc");
//filterMap.put("/user/update", "authc");
filterMap.put("/user/**", "authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录的请求
bean.setLoginUrl("/tologin");
return bean;
}
//DefaultWebSecurityManager:2
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象, 需要自定义
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
MyController.java
....
@RequestMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "index";
} catch (UnknownAccountException e){
//用户名不存在
model.addAttribute("msg", "用户名不存在");
return "login";
} catch (IncorrectCredentialsException e){
//密码不存在
model.addAttribute("msg", "密码错误");
return "login";
}
}
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http:www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/login}">
<p> 用户名: <input type="text" name="username"></p>
<p> 密码: <input type="text" name="password"></p>
<p> <input type="submit">登录</p>
</form>
</body>
</html>
Realm.java
public class UserRealm extends AuthorizingRealm {
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
//用户名、密码、数据库中取
String name = "root";
String password = "123456";
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
if (!userToken.getUsername().equals(name)){
return null; // 抛出异常 UnknownAccountException
}
//密码认证,shiro做
return new SimpleAuthenticationInfo("", password, "");
}
}
1、引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
2、数据库
3、配置数据源
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/shiro_study
driver-class-name: com.mysql.jdbc.Driver
3、代码生成器
// 代码自动生成器
public class xmhCode {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath+"/02_shiro_springboot/src/main/java");
gc.setOpen(false);
gc.setFileOverride(false); // 是否覆盖
gc.setServiceName("%sService"); // 去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/shiro_study");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.xmh");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user"); // 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setLogicDeleteFieldName("deleted");
//自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified",
FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
//乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute(); //执行
}
}
4、运行代码生成器。并且在springboot启动类上标注mapperScan()
5、测试
@SpringBootTest
class ApplicationTests {
@Autowired
UserService userService;
@Test
void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", "xmh");
User one = userService.getOne(wrapper);
System.out.println(one);
}
}
6、从数据库中查询用户名密码:
UserRealm.java
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//用户名、密码、数据库中取
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", userToken.getUsername());
User user = userService.getOne(wrapper);
if (user == null){
return null;// 抛出异常 UnknownAccountException
}
//密码认证,shiro做
return new SimpleAuthenticationInfo("", user.getPassword(), "");
}
}
7、启动测试,测试成功!
controller中新增未授权页面
...
@RequestMapping("/noauth")
@ResponseBody
public String noauth(){
return "未经授权,无法访问此页面";
}
ShiroConfig.java
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean:3
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加Shiro的内置过滤器
/*anon: 无需认证就可以访问
* authc: 必须认证了才能访问
* user:必须拥有 记住我 功能才能访问
* perms:拥有对某个资源的权限才能访问
* role:拥有某个角色权限才能访问
* */
LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
//授权,正常情况下,没有授权会跳转到未授权页面
filterMap.put("/user/add", "perms[user:add]");
filterMap.put("/user/update", "perms[user:update]");
//filterMap.put("/user/add", "authc");
//filterMap.put("/user/update", "authc");
filterMap.put("/user/**", "authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录的请求
bean.setLoginUrl("/toLogin");
//未授权 跳转到未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//DefaultWebSecurityManager:2
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建realm对象, 需要自定义
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
}
增加数据库权限字段:
Realm.java
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//拿到当前登录的这个对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到user对象
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthorizationInfo");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//用户名、密码、数据库中取
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", userToken.getUsername());
User user = userService.getOne(wrapper);
if (user == null){
return null;// 抛出异常 UnknownAccountException
}
//密码认证,shiro做
return new SimpleAuthenticationInfo(user, user.getPassword(), "");
}
}
每个人的学习方法是不同的,一个人的方法不见得适合另一个人,我只能是谈自己的学习方法。因为我学习Java是完全自学的,从来没有问过别人,所以学习的过程基本上完全是自己摸索出来的。我也不知道这种方法是否是比较好的方法,只能给大家提供一点参考了。学习Java的第一步是安装好JDK,写一个Hello World,? 其实JDK的学习没有那么简单,关于JDK有两个问题是很容易一直困扰Java程序员的
原文:https://www.jianshu.com/p/71fb7ccc05ff0.写在前面本文是笔者自学笔记,以破解某目标apk的方式进行学习,中间辅以原理性知识,方便面试需求。参考文章的原文链接会附在相应流程位置,方便阅读学习。逆向分析流程.jpg1.获取目标apk第一步是拿到目标安装包文件,这一步很简单,可...
变量和数据类型,赋值和输出算术运算选择结构循环结构函数定义,函数调用变量作用域栈,程序运行的基石 面向对象异常处理语言提供的公用包现在高级语言之所以能调用函数,能在不同的类实例切换来切换去,是得利于stack(栈)这个数据结构。栈是一种先进后出的数据结构,用图表示可参考如下:5入栈之后,栈中只有一个元素5。6再入栈后,有5和6,其中5在栈底,6在栈顶。接着,6出栈后,栈里只有5。5再出栈后,栈为空...
1.简述Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,提供HQL查询语言,使得Java程序员可以随心所欲的使用对象编程思维来操 纵数据库。使用Hibernate,必须为配置映射文件—ClassMapping File和Configuration File,现在市场上提供了诸多Hibernate代码生成工具,比如:XDoclet,以及Hibern
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>DIV水平垂直居中</title> <style type="text/css"> .max_box{ ...
#include<iostream>#include<cstdlib>#include<new>using namespace std;class T{ public: T(){ cout << "构造函数。" << endl; } ~T(){ cout << "析构函数。" << endl; } void * operator new(size_t sz){ .
创作初衷:研究生阶段,高级人工智能大作业,设计使用 IBM Cloud,完成一次实例应用。如有相关联系,大家可以参考。具体步骤比官方给出的更加详细,记得当时在云上一直无法部署成功,所以转到本地来完成。步骤1 –创建Node-RED入门应用程序(1)登录到IBM Cloud帐户。(2)单击‘目录’按钮。(3)选择Node-RED App 入门模板工具包。(4)点击‘创建’按钮。(5)输入应用程序的唯一名称。该名称将成为应用程序URL的一部分。如果名称不是唯一的,将收到一条错误消息,并需要输入另
合理设置栅格化与比例 让版式布局更友好十二月 31, 2015评论 (3)Sponsor本文不适合采用天才设计(Genius Design)方法的人士。有一种“奇怪的”现象会经常的看到“很多设计师没有办法清楚的跟其他人解释他们是如何设计的,越细致的地方可能越是如此。比如,这个菜单的宽度为什么是200px?250px或者190px是否可以?图片的尺寸为什么是278px*196px?如何确定网页的宽度..._栅格化排版
池保勇联系方式:010-62795096E-mail:[email protected]年02月出生于湖北省孝感市,1998年7月本科毕业于北京大学计算机科学与技术系微电子学专业;同年9月进入清华大学微电子学研究所直接攻读博士学位,2003年07月获工学博士学位;同年8月进入清华大学微电子学研究所工作至今,现为清华大学集成电路学院教授,设计室副主任,并于2006年11月~2007年10月之间在[email protected]
对集合一等支持而且支持闭包的语言用来描述图很方便g_text = """{ 0:[6,2,1,5], 1:[0], 2:[0], 3:[5,4], 4:[5,6,3], 5:[3,4,0], 6:[0,4], 7:[8], 9:[11,10,12], 10:[9], 11:[9,12], 12:[9..._python表示无向图
主节点:rx8640服务器HPUX 11.23操作系统IP地址128.199.38.32数据库:ORACLE 10.2.0.1ORACLE_SID:oraGlobal_name:ora副节点一(ORACLE RAC...
当上一个操作完成之后或者当某段内容输出之后,希望页面停留几秒,然后跳转到指定页面的问题!这种问题很常见,最典型的例子就是12306网站当购票付款成功之后,会停顿几秒,然后跳回到车票列表页方法一:直接利用php中的header()方法此处输出内容后,停顿三秒,然后跳转到百度首页date_default_timezone_set('Asia/Shanghai');/**此处处理业务逻辑*/echo..._php中停止三秒