Spring+Hibernate+Acegi 的初次体验

到现在我也没有弄明白Acegi里面很多的功能,刚刚开始学的时候我就已经被它那繁琐的配置震慑住了,不过当我动起手来一步步实现的时候,才发现其实它远没有那么难,当然随着学习的深入,会渐渐再发现这一点吧,现在就让我们初学者一切体验Acegi的功能吧!

还以我传统的例子为例:
毕业设计选题系统,三种角色:教师,学生,管理员,我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的admin.jsp,stu.jsp,teacher.jsp
在数据库中的表结构如下(很多属性略):
id--- user---password--type---about

type是用来存储用户的类别,分别有a,t,s分别对应三种角色
about对应的是acegi里所需要的enable,用户是否可用

在model里,我们采用了继承关系:

父类user:
[code]
package subject.model;

public abstract class User extends BaseObject
{
private Integer id;
private String user;
private String password;
private String name;
private String telphone;

//set and get method
//这个是用来反映用户角色的关键函数,在子类实现,从而实现多态
public abstract String getType();
}
[/code]

子类的实现:
======================
[code]
package subject.model;

import subject.Constants;

public class Teacher extends User
{
private String level; //教师的职称

//set and get method

public String getType()
{
return Constants.TEACHER;
}
}
[/code]
================
[code]
package subject.model;

import subject.Constants;

public class Student extends User
{
private static final long serialVersionUID = 1L;

private SchoolClass schoolClass; //学生的班级
private String sn; //学生的学号

//set and get method

public String getType()
{
return Constants.STUDENT;
}
}
[/code]
=================
[code]
package subject.model;

import subject.Constants;

public class Admin extends User
{
private String grade; //管理员的级别
//set and get method

public String getType()
{
return Constants.ADMIN;
}
}
[/code]

对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!

这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:
[code]
<hibernate-mapping>

<class name="subject.model.User" discriminator-value="not null">

<id name="id">
<generator class="increment" />
</id>

<discriminator column="type" type="character" />

<property name="user" />
<property name="password" />
<property name="name" />
<property name="telphone" />

<subclass name="subject.model.Admin" discriminator-value="a">
<property name="grade" column="sn" />
</subclass>

<subclass name="subject.model.Teacher" discriminator-value="t">
<property name="level" column="sn" />
</subclass>

<subclass name="subject.model.Student" discriminator-value="s">

<property name="sn" />

<many-to-one name="schoolClass" class="subject.model.SchoolClass"
column="about" update="false" insert="false" />

</subclass>

</class>

</hibernate-mapping>
[/code]

=============================================
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆
在Spring中Hibernate的配置只介绍不说明:
[code]
<!-- 定义DBCP数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/subject?useUnicode=true&characterEncoding=gbk" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="30" />
<property name="maxWait" value="1000" />
<property name="defaultAutoCommit" value="true" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="60" />
</bean>

<!-- Hibernate -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>subject/model/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
</props>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- Dao对象 -->
<bean id="userDao" class="subject.dao.hibernate.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- 业务逻辑 -->
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>

<bean id="userManager" parent="txProxyTemplate">
<property name="target">
<bean class="subject.service.impl.UserManagerImpl">
<property name="userDao" ref="userDao" />
</bean>
</property>
</bean>

<!-- Struts -->
<bean name="/user" class="subject.web.action.UserAction" singleton="false">
<property name="userManager">
<ref bean="userManager" />
</property>
</bean>
[/code]
==================
上面具体的不用了解,无非就是调用和数据库的操作,
下面就要对Acegi进行声明了:
我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆
我们想主要在这样的系统中需要的安全策略都有哪些?
1.用户的登陆
2.防止多个用户登陆一个帐号
3.用户的注销
4.防止非法用户的访问

我这个程序所涉及到的只有这些,下面就进行说明:

在web.xml的声明:
[code]
<!-- Acegi安全控制 Filter 配置 -->
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[/code]

Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这样就简化了web.xml的配置,并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。

[code]
<!-- ======================== FILTER CHAIN ======================= -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT

/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,
securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
[/code]

大体上先介绍一下:
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
logoutFilter:用户的注销
authenticationProcessingFilter:处理登陆请求
exceptionTranslationFilter:异常转换过滤器
filterInvocationInterceptor:在访问前进行权限检查

这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。

下面就是对这些过滤器的具体声明:
只对有用的地方进行声明,别的地方几乎都是默许的
[code]
<!-- ======================== FILTER ======================= -->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />

<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.htm" /> 离开后所转向的位置
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.htm" /> 定义用户注销的地址,
</bean>

[/code]
下面的这个过滤器,我们根据自己的需求有了自己的实现:
[code]
<bean id="authenticationProcessingFilter" class="subject.web.filter.UserAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/> 下面会介绍的用来起到认证管理的作用
<property name="authenticationFailureUrl" value="/login.htm?error=wrong"/> 登陆失败的地址
<property name="defaultTargetUrl" value="/login.htm"/> 登陆成功的地址
<property name="filterProcessesUrl" value="/j_security_check"/> 登陆请求的地址
<property name="userManager" ref="userManager"/> 自己添加的属性,这样就可以访问到我们的业务逻辑
<property name="exceptionMappings"> 出现异常所对应的地址
<value>
org.acegisecurity.AuthenticationException=/login.htm?error=fail 登陆失败 org.acegisecurity.concurrent.ConcurrentLoginException=/login.htm?error=too 已登陆了
</value>
</property>
</bean>

<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>

<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.htm?error=please"/>//如果用户没登陆就想访问,先到这里登陆吧
<property name="forceHttps" value="false"/>
</bean>
</property>
</bean>

<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/> 认证服务
<property name="accessDecisionManager">
<bean class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value=""/> //这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀?我没加
</bean>
</list>
</property>
</bean>
</property>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT

/admin.htm*=a 这里就是数据库中对应的tyep a
/student*=s 由于没有前缀和数据库里一样
/teacher*=t
</value>
</property>
</bean>

<bean id="loggerListener"
class="org.acegisecurity.event.authentication.LoggerListener"/> 记录事件

下面就要说明我们的认证服务了,其起到的关键作用就是用来保证用户登陆身份的验证:

它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。

先声明一个管理器吧,在上面的过滤器中都已经用到过了
<!-- ======================== AUTHENTICATION ======================= -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" /> 我仅仅用到 从数据库中读取用户信息验证身份
</list>
</property>
<property name="sessionController">
<bean id="concurrentSessionController"
class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="maximumSessions">
<value>1</value>每个用户同时登陆一位
</property>
<property name="sessionRegistry">
<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl" />
</property>
<property name="exceptionIfMaximumExceeded" value="true" />
</bean>
</property>
</bean>
来实现唯一的一个Provider,从数据库验证身份
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService">
<bean id="jdbcDaoImpl"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="usersByUsernameQuery">
<value>
select user,password,about from user where user = ? 查找用户的查询语句,只需要把你数据库中的用户和密码以及enable相对应上就行
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
select user,type from user where user = ? 这里就是把用户和权限对应上,在appfuse中用的两个表,我都放一个表里了,所以就用这一个就行问题的关键是要让它能找到两个字段,构成一个对象
</value>
</property>
</bean>
</property>
<property name="userCache"> 缓存都这么写:
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</property>
<property name="cacheName" value="userCache"/>
</bean>
</property>
</bean>
</property>
</bean>
[/code]
==============
对于上面登陆请求的处理器我借鉴了springSide,实现的方法如下:
[code]
package subject.web.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.acegisecurity.userdetails.UserDetails;

import subject.Constants;
import subject.model.User;
import subject.service.UserManager;

public class UserAuthenticationProcessingFilter extends
AuthenticationProcessingFilter
{
private UserManager userManager;

public void setUserManager( UserManager userManager )
{
this.userManager = userManager;
}

protected boolean requiresAuthentication( HttpServletRequest request ,
HttpServletResponse response )
{
boolean requiresAuth = super.requiresAuthentication( request, response );
HttpSession httpSession = null;
try
{
httpSession = request.getSession( false );
}
catch ( IllegalStateException ignored )
{
}
if ( httpSession != null )
{
if ( httpSession.getAttribute( Constants.USER ) == null )
{
if ( !requiresAuth )
{
SecurityContext sc = SecurityContextHolder.getContext();
Authentication auth = sc.getAuthentication();
if ( auth != null
&& auth.getPrincipal() instanceof UserDetails )
{
UserDetails ud = (UserDetails) auth.getPrincipal();//上面声明的sql无非就是要包装成这个对象
User user = userManager.getUser( ud.getUsername() );从业务逻辑里找到用户,放到session里
httpSession.setAttribute( Constants.USER, user );
}
}
}
}
return requiresAuth;
}
}
[/code]

在看看我的login.htm在登陆成功时是怎么工作的吧?
[code]
public class UserAction extends BaseAction
{
private UserManager mgr;

public void setUserManager( UserManager mgr )
{
this.mgr = mgr;
}

public ActionForward login( ActionMapping mapping , ActionForm form ,
HttpServletRequest request , HttpServletResponse response )
throws Exception
{
User user = (User) getSessionObject( request, Constants.USER );
ActionMessages msg = new ActionMessages();
if ( user != null )
{
return new ActionForward( user.getType() + ".htm", true );成功就去type.htm
}
else
{
String error = getParameter( request, Constants.ERROR );
if ( error != null )对于不同的错误,都加以提示
{
if ( error.equalsIgnoreCase( "wrong" ) )
msg.add( "msg", new ActionMessage( "fail.login.wrong" ) );
else if ( error.equalsIgnoreCase( "too" ) )
msg.add( "msg", new ActionMessage( "fail.login.too" ) );
else if ( error.equalsIgnoreCase( "fail" ) )
msg.add( "msg", new ActionMessage( "fail.login.fail" ) );
else
msg.add( "msg", new ActionMessage( "fail.login.please" ) );
}
else
msg.add( "msg", new ActionMessage( "fail.login.please" ) );
}
saveErrors( request, msg );
return mapping.findForward( "fail" );
}

}
[/code]

当然,Acegi需要介绍的东西太多了,我只把我这次认为有必要解释的东西写在了上面让大家来参考,作为能google到的东西,比如对于认证的方式还有很多,我就没有详细的介绍,在学习Acegi过程中,把它自带的例子弄清楚很关键,希望大家一起学习一起共勉!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值