精华内容
下载资源
问答
  • Java常见异常种类及产生原因
    千次阅读
    2017-12-12 11:28:08

    Java常见异常种类及产生原因


    JAVA异常共分为下列几种

    • Error JAVA环境编译错误
    • Runtime Exception 运行处异常
    • Exception 标准Java库方法异常
    • throw 用户自定义异常

    异常共分为两类

    • Error 该异常为Java变异和Java内部错误,不允许捕获。碰到该类型异常一般又环境问题导致。例如:Java环境错误,文件丢失,服务器异常,配置错误等导致。碰到类似错误处理方案一般为,重启服务,环境重新搭建等。没有其他比较好的处理方案。
    • Exception 可捕获的系统异常,该类型的异常包含Runtime Exception(运行时异常)和Non RuntimeException(非运行异常)碰到类似的异常需要我们开发人员手动处理业务代码修复,或对异常进行捕获并处理。
      • 运行异常类对应于编译错误,它是指Java程序在运行时产生的由解释器引发的各种异常。运行异常可能出现在任何地方,且出现频率很高,因此为了避免巨大的系统资源开销,编译器不对异常进行检查。所以Java语言中的运行异常不一定被捕获。出现运行错误往往表示代码有错误,如:算数异常(如被0除)、下标异常(如数组越界)等。
      • 非运行异常时Non_RuntimeException类及其子类的实例,又称为可检测异常。Java编译器利用分析方法或构造方法中可能产生的结果来检测Java程序中是否含有检测异常的处理程序,对于每个可能的可检测异常,方法或构造方法的throws子句必须列出该异常对应的类。在Java的标准包java.lang java.util 和 java.net 中定义的异常都是非运行异常。

    常见异常汇总

    • ArithmeticExecption|算术异常类.
    • NullPointerException|空指针异常类.
    • ClassCastException|类型强制转换异常.
    • NegativeArrayException|数组负下标异常.
    • ArrayIndexOutOfBoundsException|数组下标越界异常.
    • SecturityException|违背安全原则异常.
    • EOFException|文件已结束异常.
    • FileNotFoundException|文件未找到异常.
    • NumberFormatException|字符串转换为数字异常.
    • SQLException|操作数据库异常.
    • IOException|输入输出异常.
    • NoSuchMethodException|方法未找到异常.
    • java.lang.AbstractMethodError|抽象方法错误。当应用试图调用抽象方法时抛出.
    • java.lang.AssertionError|断言错。用来指示一个断言失败的情况.
    • java.lang.ClassCircularityError|类循环依赖错误。在初始化一个类时,若检测到类之间循环依赖则抛出该异常.
    • java.lang.ClassFormatError|类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出.
    • java.lang.Error|错误。是所有错误的基类,用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况.
    • java.lang.ExceptionInInitializerError|初始化程序错误。当执行一个类的静态初始化程序的过程中,发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段.
    • java.lang.IllegalAccessError|违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常.
    • java.lang.IncompatibleClassChangeError|不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时,抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下,容易引发该错误.
    • java.lang.InstantiationError|实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.
    • java.lang.InternalError|内部错误。用于指示Java虚拟机发生了内部错误.
    • java.lang.LinkageError|链接错误。该错误及其所有子类指示某个类依赖于另外一些类,在该类编译之后,被依赖的类改变了其类定义而没有重新编译所有的类,进而引发错误的情况.
    • java.lang.NoClassDefFoundError|未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类,而找不到该类的定义时抛出该错误.
    • java.lang.NoSuchFieldError|域不存在错误。当应用试图访问或者修改某类的某个域,而该类的定义中没有该域的定义时抛出该错误.
    • java.lang.NoSuchMethodError|方法不存在错误。当应用试图调用某类的某个方法,而该类的定义中没有该方法的定义时抛出该错误.
    • java.lang.OutOfMemoryError|内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误.
    • java.lang.StackOverflowError|堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误.
    • java.lang.ThreadDeath|线程结束。当调用Thread类的stop方法时抛出该错误,用于指示线程结束.
    • java.lang.UnknownError|未知错误。用于指示Java虚拟机发生了未知严重错误的情况.
    • java.lang.UnsatisfiedLinkError|未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出.
    • java.lang.UnsupportedClassVersionError|不支持的类版本错误。当Java虚拟机试图从读取某个类文件,但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候,抛出该错误.
    • java.lang.VerifyError|验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误.
    • java.lang.VirtualMachineError|虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况.
    • java.lang.ArithmeticException|算术条件异常。譬如:整数除零等.
    • java.lang.ArrayIndexOutOfBoundsException|数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出.
    • java.lang.ArrayStoreException|数组存储异常。当向数组中存放非数组声明类型对象时抛出.
    • java.lang.ClassCastException|造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。
    • java.lang.ClassNotFoundException|不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
    • java.lang.CloneNotSupportedException|支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。
    • java.lang.EnumConstantNotPresentException|举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象,但该枚举对象并不包含常量时,抛出该异常。
    • java.lang.Exception|异常。用以描述应用程序希望捕获的情况。
    • java.lang.IllegalAccessException|法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法,而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。
    • java.lang.IllegalMonitorStateException|法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。
    • java.lang.IllegalStateException|法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态,而调用了该方法时,抛出该异常。
    • java.lang.IllegalThreadStateException|法的线程状态异常。当县城尚未处于某个方法的合法调用状态,而调用了该方法时,抛出异常。
    • java.lang.IndexOutOfBoundsException|引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。
    • java.lang.InstantiationException|例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。
    • java.lang.InterruptedException|中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态,而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。
    • java.lang.NegativeArraySizeException|组大小为负值异常。当使用负数大小值创建数组时抛出该异常。|ava.lang.NoSuchFieldException|性不存在异常。当访问某个类的不存在的属性时抛出该异常。
    • java.lang.NoSuchMethodException|法不存在异常。当访问某个类的不存在的方法时抛出该异常。
    • java.lang.NullPointerException|指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
    • java.lang.NumberFormatException|字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。
    • java.lang.RuntimeException|行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类。|ava.lang.SecurityException|全异常。由安全管理器抛出,用于指示违反安全情况的异常。
    • java.lang.StringIndexOutOfBoundsException|符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常。
    • java.lang.TypeNotPresentException|型不存在异常。当应用试图以某个类型名称的字符串表达方式访问该类型,但是根据给定的名称又找不到该类型是抛出该异常。该异常与ClassNotFoundException的区别在于该异常是unchecked(不被检查)异常,而ClassNotFoundException是checked(被检查)异常。
    • java.lang.UnsupportedOperationException|支持的方法异常。指明请求的方法不被支持情况的异常。

    其他

    异常
    javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login (/Login是你的action名字)

    可能原因
    action没有再struts-config.xml 中定义,或没有找到匹配的action,例如在JSP文件中使用


    异常
    org.apache.jasper.JasperException: Cannot retrieve definition for form bean null

    可能原因
    这个异常是因为Struts根据struts-config.xml中的mapping没有找到action期望的form bean。大部分的情况可能是因为在form-bean中设置的name属性和action中设置的name属性不匹配所致。换句话说,action和form都应该各自有一个name属性,并且要精确匹配,包括大小写。这个错误当没有name属性和action关联时也会发生,如果没有在action中指定name属性,那么就没有name属性和action相关联。当然当action制作某些控制时,譬如根据参数值跳转到相应的jsp页面,而不是处理表单数据,这是就不用name属性,这也是action的使用方法之一。


    异常
    No action instance for path /xxxx could be created

    可能原因
    特别提示:因为有很多中情况会导致这个错误的发生,所以推荐大家调高你的web服务器的日志/调试级别,这样可以从更多的信息中看到潜在的、在试图创建action类时发生的错误,这个action类你已经在struts-config.xml中设置了关联(即添加了标签)。

    在struts-config.xml中通过action标签的class属性指定的action类不能被找到有很多种原因,例如:定位编译后的.class文件失败。Failure to place compiled .class file for the action in the classpath (在web开发中,class的的位置在r WEB-INF/classes,所以你的action class必须要在这个目录下。例如你的action类位于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设置action的属性type时就是action.Login).
    拼写错误,这个也时有发生,并且不易找到,特别注意第一个字母的大小写和包的名称。


    异常
    javax.servlet.jsp.JspException: No getter method for property username of bean org.apache.struts.taglib.html.BEAN

    可能原因
    没有位form bean中的某个变量定义getter 方法

    这个错误主要发生在表单提交的FormBean中,用struts标记时,在FormBean中必须有一个getUsername()方法。注意字母“U”。


    异常
    java.lang.NoClassDefFoundError: org/apache/struts/action/ActionForm

    可能原因
    这个错误主要发生在在classpath中找不到相应的Java .class文件。如果这个错误发生在web应用程序的运行时,主要是因为指定的class文件不在web server的classpath中(/WEB-INF/classes 和 /WEB-INF/lib)。在上面的错误中,原因是找不到ActionForm类。


    异常
    javax.servlet.jsp.JspException: Exception creating bean of class org.apache.struts.action.ActionForm: {1}

    可能原因
    Instantiating Struts-provided ActionForm class directly instead of instantiating a class derived off ActionForm. This mightoccur implicitly if you specify that a form-bean is this Struts ActionForm class rather than specifying a child of this classfor the form-bean.

    Not associating an ActionForm-descended class with an action can also lead to this error.


    异常
    javax.servlet.jsp.JspException: Cannot find ActionMappings or ActionFormBeans collection

    可能原因
    不是标识Struts actionServlet的标记就是映射.do扩展名的标记或者两者都没有在web.xml中声明。

    在struts-config.xml中的打字或者拼写错误也可导致这个异常的发生。例如缺少一个标记的关闭符号/>。最好使用struts console工具检查一下。

    另外,load-on-startup必须在web.xml中声明,这要么是一个空标记,要么指定一个数值,这个数值用来表servlet运行的优先级,数值越大优先级越低。

    还有一个和使用load-on-startup有关的是使用Struts预编译JSP文件时也可能导致这个异常。


    异常
    java.lang.NullPointerException at org.apache.struts.util.RequestUtils.forwardURL(RequestUtils.java:1223)

    可能原因
    在struts-config.xml中的forward元素缺少path属性。例如应该是如下形式:


    异常
    javax.servlet.jsp.JspException: Cannot find bean org.apache.struts.taglib.html.BEAN in any scope

    Probable Causes
    试图在Struts的form标记外使用form的子元素。这常常发生在你在

    后面使用Struts的html标记。另外要注意可能你不经意使用的无主体的标记,如

    更多相关内容
  • Java Web框架篇之Spring

    万次阅读 多人点赞 2019-06-04 17:41:31
    Web发展的几个阶段 (1)初级阶段:使用Model1(JSP+JavaBean)/Model2(Jsp+Servlet+JavaBean)/三层模型(表示层(JSP/Servlet)+业务逻辑层+持久化层)进行开发; (2)中级阶段:使用EJB进行分布式应用开发,忍受...

    Java Web系列文章汇总贴: Java Web知识总结汇总


    为什么要有Spring(IoC)

    Web发展的几个阶段

    • (1)初级阶段:使用Model1(JSP+JavaBean)/Model2(Jsp+Servlet+JavaBean)/三层模型(表示层(JSP/Servlet)+业务逻辑层+持久化层)进行开发;
    • (2)中级阶段:使用EJB进行分布式应用开发,忍受重量级框架带来的种种麻烦;
    • (3)高级阶段:使用Spring春天带给我们的美好,但是还要忍受很多繁琐的配置;
    • (4)骨灰级阶段:使用Spring Boot,畅享“预定大于配置”带给我们的种种乐趣!

    Web发展初级阶段存在的问题

    • 1、面向接口编程的实例化对象,每一个方法中都需要进行实例化我们需要用到的接口的实现类,这就会存在大量的实例化对象,并且他们的生命周期可能就是从方法的调用开始到方法的调用结束为止,加大了GC回收的压力!
    • 2、使用单例模式的一次改进,使用单例模式的方式来解决这个问题,以此来避免大量重复的创建对象,但是我们还要考虑到众多的这种对象的创建都需要改成单例模式的话,是一个耗时耗力的操作。对于这个系统来说,如果都把这种面向接口的对象实现类转换为单例模式的方式的话,大概也要写十几个或者上百个这种单例模式代码,而对于一个单例模式的写法来说,往往是模板式的代码。
    • 3、使用工厂模式创建对象,也会存在大量的工厂、模板式代码,需要自己管理复杂的实例依赖关系,而且代码的耦合性较高

    可以看出,这种方式有两个问题:
    (1)业务代码与单例/工厂模式的模板代码放在一个类里,耦合性较高;
    (2)大量重复的单例/工厂模式的模板代码,需要自己管理对象间复杂的依赖关系

    更多:
    通过Web开发演进过程了解一下为什么要有Spring


    Spring概述

    是什么?

    一个开源的轻量级开发框架,是为了解决企业应用程序的复杂性而创建的。

    为什么?

    EJB时代,企业级应用开发困难。Spring设计初衷是使JavaEE更加容易,为JavaBean提供配置框架,使程序易于测试,设计目标是简单易用,与应用程序解耦,致力于集成其他解决方案,而不是竞争。Spring不仅仅限于服务器端的开发,从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中学习受益。

    怎么做?

    Spring包括Core+Context,Aop,Dao,ORM,Web(SpringMVC),JEE 等模块。
    Spring框架概述

    这里着重介绍下Ioc和Aop两大核心模块。

    IoC简介

    IoC(Inversion of Control)控制反转,对象创建责任的反转,在spring中BeanFacotory是IoC容器的核心接口,负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。XmlBeanFacotory实现BeanFactory接口,通过获取xml配置文件数据,组成应用对象及对象间的依赖关系。
    spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入。

    IOC,字面理解是控制反转,即对象的控制权被反转了(是什么)。之前一个对象中依赖另一个对象,需要自己new出来,当对象间的依赖关系非常复杂时,这个过程就变得很繁琐,并且代码间的耦合会很高。现在可以通过Ioc容器来管理控制对象的生成,可以把对象的实例化过程简单化,代码间解耦(为什么)。具体可以从DI(Dependency Injection) DL(Dependency Lookup)两个角度理解Ioc。DI中注入的方式包括属性,构造器,setter注入,DL含义是通过容器的API来查找所依赖的资源和协作对象,从Ioc容器维护的bean map中取出来(怎么做)

    Aop简介

    Aop就是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

    为什么?
    利用Aop可以对业务逻辑的各部分进行隔离,从而降低各部分耦合度,提高程序的可重用性,提高开发效率

    怎么做?
    spring中面向切面变成的实现有两种方式,一种是动态代理,一种是CGLIB,动态代理必须要提供接口,而CGLIB实现是有继承,即,

    • 接口+实现类,spring采用jdk的动态代理实现,
    • 实现类,spring采用cglib字节码增强实现。

    当然也可以通过集成AspectJ可以更方便的实现自定义切面。Spring Aop支持前/后/环绕等多种类型的通知机制:

    • before(前置通知):在一个方法之前执行的通知。
    • after(最终通知):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
    • after-returning(后置通知):在某连接点正常完成后执行的通知。
    • after-throwing(异常通知):在方法抛出异常退出时执行的通知。
    • around(环绕通知):在方法调用前后触发的通知。

    好处?

    • 轻量级的容器框架没有侵入性
    • 使用IoC容器更加容易组合对象直接间关系,面向接口编程,降低耦合
    • Aop可以更加容易的进行功能扩展,遵循ocp开发原则
    • 创建对象默认是单例的,不需要再使用单例模式进行处理
    • 基于Ioc Aop,Spring提供了事务管理,Spring Web,日志等一系列经典应用

    缺点?

    • 业务功能依赖spring特有的功能,依赖与spring环境。

    更多:
    Spring框架介绍及使用
    Spring简介
    AOP实践(AspectJ)-日志实现


    Spring IoC

    Ioc理解

    IOC(DI):java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成。通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关系业务逻辑本身就可以了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。

    这是我对Spring的IOC的体会。DI其实就是IOC的另外一种说法。DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。

    如果对这一核心概念还不理解:这里引用一个叫Bromon的blog上找到的浅显易懂的答案:

    IoC与DI

    • 首先想说说IoC(Inversion of Control,控制倒转)。
      这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。举个例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号…,想办法认识她们,投其所好送其所好,然后嘿嘿…这个过程是复杂深奥的,我们必须自己设计和面对每个环节。
      传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类耦合起来。

    • 那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。

    • Spring所倡导的开发方式就是如此:所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

    • IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。
      那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

    摘自:
    最好理解的: spring ioc原理讲解,强烈推荐
    控制反转和依赖注入的理解(通俗易懂)
    Spring源码剖析——核心IOC容器原理
    Spring源码剖析——依赖注入实现原理


    Spring装配Bean

    生命周期流程图

     Spring Bean的完整生命周期

    以BeanFactory为例,说明一个Bean的生命周期活动

    • Bean的建立, 由BeanFactory读取Bean定义文件,并生成各个实例
    • Setter注入,执行Bean的属性依赖注入
    • BeanNameAware的setBeanName(), 如果实现该接口,则执行其setBeanName方法
    • BeanFactoryAware的setBeanFactory(),如果实现该接口,则执行其setBeanFactory方法
    • BeanPostProcessor的processBeforeInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processBeforeInitialization()方法
    • InitializingBean的afterPropertiesSet(),如果实现了该接口,则执行其afterPropertiesSet()方法
    • Bean定义文件中定义init-method
    • BeanPostProcessors的processAfterInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processAfterInitialization()方法
    • DisposableBean的destroy(),在容器关闭时,如果Bean类实现了该接口,则执行它的destroy()方法
    • Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法

    Spring装配Bean的过程

    装配bean过程

    1. 实例化;
    2. 设置属性值;
    3. 如果实现了BeanNameAware接口,调用setBeanName设置Bean的ID或者Name;
    4. 如果实现BeanFactoryAware接口,调用setBeanFactory 设置BeanFactory;
    5. 如果实现ApplicationContextAware,调用setApplicationContext设置ApplicationContext
    6. 调用BeanPostProcessor的预先初始化方法;
    7. 调用InitializingBean的afterPropertiesSet()方法;
    8. 调用定制init-method方法;
    9. 调用BeanPostProcessor的后初始化方法;

    Spring容器关闭过程

    1. 调用DisposableBean的destroy();
    2. 调用定制的destroy-method方法;

    其他说明

    懒加载:就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中。

    spring配置文件中bean默认是lazy-init=“false”为非懒加载。下面具体说明。

    1、默认情况下bean实例化过程:
    AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("/beans.xml"); //随着spring容器加载,就实例化了bean。

    2、给bean设置 lazy-init=“true”
    AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("/beans.xml"); //随着spring容器加载,就不会实例化bean。
    Person person = ctx.getBean(“person”);//这一步才在实例化bean。就是前面说的需要的时候再实例化了。

    简单描述实例化bean的过程如下:

    实例化bean测试结果:先构造函数——>然后是b的set方法注入—— >InitializingBean 的afterPropertiesSet方法——>init- method方法

    相关:
    Spring Bean的生命周期(非常详细)
    Spring Bean的生命周期
    Spring学习之Bean详解


    为什么要有Spring AOP

    存在的问题

    业务代码已经被这些非核心的代码所混淆,并且占据了大量的空间!显然这种显示的调用过程成为了我们开发过程中的一个痛点,如何将类似这种的非核心的代码剥离出去成为一个迫切需要解决的问题。
    诸如日志记录,登录权限控制,还有数据库事务的控制,数据库连接的创建和关闭等等,这些都充斥这大量重复性的模板代码!

    使用设计模式进行一次改进

    可以应用JDK动态代理设计模式(动态代理设计模式可以在原有的方法前后添加判断、选择或其他逻辑)。

    SpringAOP的实现

    AOP思想

    在动态代理的invoke方法里边,我们相当于在原有方法的调用前后“植入”了我们的通用日志记录代码,如果你看到这一层的话,那么恭喜你!你已经领悟到了AOP思想最核心的东西了!上述抽取公共代码其实就是AOP中横切的过程,代理对象中在方法调用前后“植入”自己写的通用日志记录代码其实就是AOP中织入的过程!这个织入的代码也就是横切逻辑,织入代码的过程其实就是在原有的方法前后增强 原方法的过程!总的来说,我们想解决我们开发中的痛点,然后就出现了一种技术,这种技术手段就是AOP。

    AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容(Spring核心之一),是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    Spring AOP

    AOP与SpringAOP

    AOP是一种思想,不同的厂商或企业可能有不同的实现方式,为了更好的应用AOP技术,技术专家们成立了AOP联盟来探讨AOP的标准化,AOP联盟定义的AOP体系结构把与AOP相关的概念大致分为由高到低、从使用到实现的三层关系。
    在AOP联盟定义的AOP体系结构下有很多的实现者,例如:AspectJ、AspectWerkz、JBoss AOP、Spring AOP等。Spring AOP就是在此标准下产生的。

    Spring AOP的实现方式

    • 通过动态代理的方式实现了简单的AOP,但是值得注意的是,我们的代理目标对象必须实现一个接口,要是一个接口的实现类,这是因为再生成Proxy对象的时候这个方法需要一个目标对象的接口。
    • 对于没有接口的对象,Spring使用CGLib的代理方式实现了这种诉求。CGLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势的织入横切逻辑。这两种方式已经实现了我们绝大多数的场景

    参考;
    通过Web开发演进过程了解一下为什么要有Spring AOP
    Spring历史版本变迁和如今的生态帝国


    Spring AOP中的JDK和CGLib动态代理

    概述

    JDK动态代理主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑贬值在一起。

    JDK动态代理的话,他有一个限制,就是它只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,如何创建动态代理实例哪?答案就是CGLib。

    CGLib采用底层的字节码技术,全称是:Code Generation Library,CGLib可以为一个类创建一个子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。

    区别

    1、JDK动态代理具体实现原理:

    • 通过实现InvocationHandlet接口创建自己的调用处理器;
    • 通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理;
    • 通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;
    • 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;

    JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。

    2、CGLib动态代理:

    CGLib是一个强大、高性能的Code生产类库,可以实现运行期动态扩展java类,Spring在运行期间通过 CGlib继承要被动态代理的类,重写父类的方法,实现AOP面向切面编程呢。

    3、两者对比:

    JDK动态代理是面向接口的。

    CGLib动态代理是通过字节码底层继承要代理类来实现(如果被代理类被final关键字所修饰,那么抱歉会失败)。

    4、使用注意:

    如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制);

    如果要被代理的对象不是个实现类那么,Spring会强制使用CGLib来实现动态代理。

    二者性能对比

    教科书上的描述:

    JDK动态代理所创建的代理对象,在以前的JDK版本中,性能并不是很高,虽然在高版本中JDK动态代理对象的性能得到了很大的提升,但是他也并不是适用于所有的场景。主要体现在如下的两个指标中:

    1、CGLib所创建的动态代理对象在实际运行时候的性能要比JDK动态代理高不少,有研究表明,大概要高10倍;
    2、但是CGLib在创建对象的时候所花费的时间却比JDK动态代理要多很多,有研究表明,大概有8倍的差距;
    3、因此,对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理,反正,则比较适用JDK动态代理。

    实际验证结论

    在1.6和1.7的时候,JDK动态代理的速度要比CGLib动态代理的速度要慢,但是并没有教科书上的10倍差距,在JDK1.8的时候,JDK动态代理的速度已经比CGLib动态代理的速度快很多了

    摘自:
    Spring AOP中的JDK和CGLib动态代理哪个效率更高

    动态代理的原理

    JDK动态代理原理:反射机制,运行时增强
    CGLib代理原理:字节码,改变字节码的编译,运行期增强
    AspectJ:静态代理,编译时改变

    参考:
    动态代理的原理及其应用
    Java动态代理的两种实现方法
    java动态代理原理及解析

    AspectJ原理及与动态代理区别

    参考:
    Spring AOP 实现原理----AspectJ与CGLIB介绍
    静态代理和动态代理的理解
    java经典讲解-静态代理和动态代理的区别


    Spring AOP的应用

    • 日志、数据库读写分离框架
    • Spring事务
    • SpringMVC

    相关:
    AOP实践(AspectJ)-日志实现
    使用Spring AOP实现MySQL数据库读写分离案例分析
    JDK动态代理给Spring事务埋下的坑
    Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别


    Spring知识点

    Spring常见问答总结(超详细回答)
    myBatis+Spring+SpringMVC框架知识点(一)
    myBatis+Spring+SpringMVC框架知识点(二)

    展开全文
  • 下面是我为大家整理的2021最新的Java面试题及答案下载,这套Java面试题汇总了Java基础面试到高级Java面试题,几乎涵盖了作为一个Java程序员在面试中需要掌握或者可能被问到的绝大部分知识点。 适宜阅读人群 需要...

    大家好!听说有很多java学习者在找有关java的面试题集,听到这个消息我来了!

    下面是我为大家整理的2021最新的Java面试题及答案下载,这套Java面试题汇总了Java基础面试到高级Java面试题,几乎涵盖了作为一个Java程序员在面试中需要掌握或者可能被问到的绝大部分知识点。

    适宜阅读人群

    • 需要面试的初/中/高级 java 程序员

    • 想要查漏补缺的人

    • 想要不断完善和扩充自己 Java 技术栈的人

    • Java 面试官

    更多2021最新Java面试题全部答案及Java零基础入门教程资料都已经给大家整理好了,大家需要的可以自行下载:

    Java考试_Java笔试题机试题真题讲解_JavaWeb阶段考试_Java期末考试通关_Java编程_Java程序员面试题_日常学习

    图标

    Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通

    图标

    Web方面相关:

    1.WEB应用中如果有.class和.jar类型的文件一般分别应该放在什么位置?

    答:.class文件放在WEB-INF/classes文件下,.jar文件放在WEB-INF/lib文件夹下

    2.元素中有一个输入框(< input type='text' name=”username”id=”username”value=””/>,请用JavaScript语言写一行代码,取得这个输入框中的值。

    答:document.getElementById(“username”).value;

    3.简单描述一下Servlet与JSP的的相同点和区别点。

    区别:

    JSP是在HTML代码里写JAVA代码,框架是HTML;而Servlet是在JAVA代码中写HTML代码,本身是个JAVA类。

    JSP使人们把显示和逻辑分隔成为可能,这意味着两者的开发可并行进行;而Servlet并没有把两者分开。

    Servlet独立地处理静态表示逻辑与动态业务逻辑.这样,任何文件的变动都需要对此服务程序重新编译;JSP允许用特殊标签直接嵌入到HTML页面, HTML内容与JAVA内容也可放在单独文件中,HTML内容的任何变动会自动编译装入到服务程序.

    Servlet需要在web.xml中配置,而JSP无需配置。

    目前JSP主要用在视图层,负责显示,而Servlet主要用在控制层,负责调度

    联系:

    都是Sun公司推出的动态网页技术。

    先有Servlet,针对Servlet缺点推出JSP。JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例——JSP页面由系统翻译成Servlet,Servlet再负责响应用户请求。

    4.请简单描述下几个您熟悉JavaScript库,它们有哪些作用和特点?

    JavaScript 高级程序设计(特别是对浏览器差异的复杂处理),通常很困难也很耗时。为了应对这些调整,许多的 JavaScript库应运而生。这些 JavaScript 库常被称为 JavaScript 框架。

    jQuery:

    Ext JS - 可定制的 widget,用于构建富因特网应用程序(rich Internet applications)。

    Prototype

    MooTools。

    YUI - Yahoo! User Interface Framework,涵盖大量函数的大型库,从简单的 JavaScript 功能到完整的 internet widget。

    5.简单描述HTML,CSS,Javascript在Web开发中分别起什么作用?

    1、什么是HTML(超文本标记语言 Hyper Text Markup Language),HTML 是用来描述网页的一种语言。

    2、CSS(层叠样式表 Cascading Style Sheets),样式定义如何显示 HTML 元素,语法为:selector {property:value} (选择符 {属性:值})

    3、JavaScript是一种脚本语言,其源代码在发往客户端运行之前不需经过编译,而是将文本格式的字符代码发送给浏览器由浏览器解释运行

    对于一个网页,HTML定义网页的结构,CSS描述网页的样子,JavaScript设置一个很经典的例子是说HTML就像 一个人的骨骼、器官,而CSS就是人的皮肤,有了这两样也就构成了一个植物人了,加上javascript这个植物人就可以对外界刺激做出反应,可以思 考、运动、可以给自己整容化妆(改变CSS)等等,成为一个活生生的人。

    如果说HTML是肉身、CSS就是皮相、Javascript就是灵魂。没有Javascript,HTML+CSS是植物人,没有Javascript、CSS是个毁容的植物人。

    如果说HTML是建筑师,CSS就是干装修的,Javascript是魔术师。

    6.当DOM加载完成后要执行的函数,下面哪个是正确的()

    7.举例说明JAVA中如何解析xml,不同方式有和优缺点?

    答:1. DOM(Document Object Model)

    DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。

    【优点】

    ①允许应用程序对数据和结构做出更改。

    ②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

    【缺点】

    ①通常需要加载整个XML文档来构造层次结构,消耗资源大。

    2. SAX(Simple API for XML)

    SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。

    选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说, 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的是事件模型。

    DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。

    SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

    【优势】

    ①不需要等待所有数据都被处理,分析就能立即开始。

    ②只在读取数据时检查数据,不需要保存在内存中。

    ③可以在某个条件得到满足时停止解析,不必解析整个文档。

    ④效率和性能较高,能解析大于系统内存的文档。

    【缺点】

    ①需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂。

    ②单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath。

    3. JDOM(Java-based Document Object Model)

    JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。

    JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。

    JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。

    JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。

    【优点】

    ①使用具体类而不是接口,简化了DOM的API。

    ②大量使用了Java集合类,方便了Java开发人员。

    【缺点】

    ①没有较好的灵活性。

    ②性能较差。

    4. DOM4J(Document Object Model for Java)

    虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。

    为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。

    在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。

    DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.

    【优点】

    ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。

    ②支持XPath。

    ③有很好的性能。

    【缺点】

    ①大量使用了接口,API较为复杂。

    二、比较

    1. DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.

    2. JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出,但可移植。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。

    3. SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。

    我的看法:如果XML文档较大且不考虑移植性问题建议采用DOM4J;如果XML文档较小则建议采用JDOM;如果需要及时处理而不需要保存数据则考虑SAX。但无论如何,还是那句话:适合自己的才是最好的,如果时间允许,建议大家讲这四种方法都尝试一遍然后选择一种适合自己的即可。

    8.char型变量中能不能存储一个中文汉字?

    答:1.java采用unicode编码,2个字节(16位)来表示一个字符, 无论是汉字还是数字,字母,或其他语言都可以存储。

    2.char 在java中是2个字节,所以可以存储中文

    9.一个类可以实现多个接口,但只能继承一个抽象类。

    下面接着再说说两者在应用上的区别:

    接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:

    父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。

    备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

    10.比较一下Java 和JavaSciprt

    答:JavaScript 与Java是两个公司开发的不同的两个产品。Java 是原Sun 公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言,它的前身是LiveScript;而Java 的前身是Oak语言。

    下面对两种语言间的异同作如下比较:

    1)基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;

    2)解释和编译:Java 的源代码在执行之前,必须经过编译;JavaScript 是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行;

    3)强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型;

    4)代码格式不一样。

    补充:上面列出的四点是原来所谓的标准答案中给出的。其实Java和JavaScript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而JavaScript中函数(function)是一等公民。对于这种问题,在面试时还是用自己的语言回答会更加靠谱。

    11.什么时候用assert?

    答:assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后, assertion检查通常是关闭的。在实现中,断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式计算为false,那么系统会报告一个AssertionError。

    断言用于调试目的:

    assert(a > 0); // throws an AssertionError if a <= 0

    断言可以有两种形式:

    assert Expression1;

    assert Expression1 : Expression2 ;

    Expression1 应该总是产生一个布尔值。

    Expression2 可以是得出一个值的任意表达式;这个值用于生成显示更多调试信息的字符串消息。

    断言在默认情况下是禁用的,要在编译时启用断言,需使用source 1.4 标记:

    javac -source 1.4 Test.java

    要在运行时启用断言,可使用-enableassertions 或者-ea 标记。

    要在运行时选择禁用断言,可使用-da 或者-disableassertions 标记。

    要在系统类中启用断言,可使用-esa 或者-dsa 标记。还可以在包的基础上启用或者禁用断言。可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。

    12.UML是什么?UML中有哪些图?

    答:UML是统一建模语言(Unified Modeling Language)的缩写,它发表于1997年,综合了当时已经存在的面向对象的建模语言、方法和过程,是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持。使用UML可以帮助沟通与交流,辅助应用设计和文档的生成,还能够阐释系统的结构和行为。UML定义了多种图形化的符号来描述软件系统部分或全部的静态结构和动态结构,包括:用例图(use case diagram)、类图(class diagram)、时序图(sequence diagram)、协作图(collaboration diagram)、状态图(statechart diagram)、活动图(activity diagram)、构件图(component diagram)、部署图(deployment diagram)等。在这些图形化符号中,有三种图最为重要,分别是:用例图(用来捕获需求,描述系统的功能,通过该图可以迅速的了解系统的功能模块及其关系)、类图(描述类以及类与类之间的关系,通过该图可以快速了解系统)、时序图(描述执行特定任务时对象之间的交互关系以及执行顺序,通过该图可以了解对象能接收的消息也就是说对象能够向外界提供的服务)。

    用例图:

    13.XML 文档定义有几种形式?它们之间有何本质区别?解析XML 文档有哪几种方式?

    答: XML文档定义分为DTD和Schema两种形式;其本质区别在于Schema本身也是一个XML文件,可以被XML解析器解析。对XML的解析主要有DOM(文档对象模型)、SAX、StAX(JDK 1.6中引入的新的解析XML的方式,Streaming API for XML) 等,其中DOM处理大型文件时其性能下降的非常厉害,这个问题是由DOM 的树结构所造成的,这种结构占用的内存较多,而且DOM 必须在解析文件之前把整个文档装入内存,适合对XML 的随机访问(典型的用空间换取时间的策略);SAX是事件驱动型的XML解析方式,它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML 的顺序访问;如其名称所暗示的那样,StAX把重点放在流上。实际上,StAX与其他方法的区别就在于应用程序能够把XML作为一个事件流来处理。将XML作为一组事件来处理的想法并不新颖(事实上 SAX 已经提出来了),但不同之处在于StAX允许应用程序代码把这些事件逐个拉出来,而不用提供在解析器方便时从解析器中接收事件的处理程序。

    14.你在项目中哪些地方用到了XML?

    答: XML的主要作用有两个方面:数据交换(曾经被称为业界数据交换的事实标准,现在此项功能在很多时候都被JSON取代)和信息配置。在做数据交换时,XML将数据用标签组装成起来,然后压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再从XML文件中还原相关信息进行处理。目前很多软件都使用XML来存储配置信息,很多项目中我们通常也会将作为配置的硬代码(hard code)写在XML文件中,Java的很多框架也是这么做的。

    15.用JavaScript实现用正则表达式验证,某个字符串是合法的6位数字的邮编的函数

    16.请使用JQuery将页面上的所有元素边框设置为2pix宽的虚线?

    $(“*”).css(“border”,”2px dashed”)

    17.如何设定JQuery异步调用还是同步调用?

    答案:调用jQuery中的ajax函数,设置其async属性来表明是异步还是同步,如下:

    $.ajax({ async:true//表示异步,false表示同步 })

    18.说出3条以上firefox和IE的浏览器兼容问题?

    答案:兼容firefox的 outerHTML,FF中没有outerHtml的方法

    IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象.解决方法:统一使用[]获取集合类对象.

    IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性;Firefox下,只能使用getAttribute()获取自定义属性.解决方法:统一通过getAttribute()获取自定义属性

    19.请用Jquery语言写出ajax请求或者post请求代码

    20.body中的onload ()函数和jQuery中document.ready()有什么区别?

    答案:ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件)

    onload 事件的触发,表示页面包含图片等文件在内的所有元素都加载完成。

    21.jQuery中有哪几种类型的选择器?

    答案:

    基本选择器

    层次选择器

    基本过滤选择器

    内容过滤选择器

    可见性过滤选择器

    属性过滤选择器

    子元素过滤选择器

    表单选择器

    表单过滤选择器

    22.EasyUI中datagrid刷新当前数据的方法?

    答案:使用reload()即可

    23.分别写出一个div居中和其中的内容居中的css属性设置

    Div居中:

    margin:auto 0px;

    内容居中:

    text-align:center;

    24.概述一下session与cookie的区别

    答案:

    存储角度:

    Session是服务器端的数据存储技术,cookie是客户端的数据存储技术

    解决问题角度:

    Session解决的是一个用户不同请求的数据共享问题,cookie解决的是不同请求的请求数据的共享问题

    生命周期角度:

    Session的id是依赖于cookie来进行存储的,浏览器关闭id就会失效

    Cookie可以单独的设置其在浏览器的存储时间。

    25.JavaScript 中 null和 undefined 是否有区别?有哪些区别?

    答案:

    赋值角度说明:

    null 表示此处没有值,undefined表示此处定义了但是没有赋值

    从数据转换角度:

    Null在做数值转换时会被转换为0,undefined会被转换为NaN

    26.Servlet中的doPost和doGet方法有什么区别?它们在传递和获取参数上有什么区别?

    答案:

    区别:doPost用来处理post请求,doGet用来处理get请求,获取参数:获取的参数是相同的都是HttpServletRequest \HttpServletResponse

    27.请写出一段jQuery代码,实现把当前页面中所有的a元索中class 属性为“view-link”的链接都改为在新窗口中打开

    答案:$(“a[class=view-link]”).attr(“target”,”_blank”)

    28.如下JavaScript代码的输出为:

    29.Jquery中’.get()’与’.eq()’的区别

    eq返回的是一个jquery对象 get返回的是一个html对象

    30.如何给weblogic定内存的大小?

    在启动Weblogic的脚本中(位于所在Domian对应服务器目录下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以调整最小内存为32M,最大200M

    以上是java面试题集中有关java Web的部分面试题整理,需要完整版面试题集的朋友们,评论区留言或私信,我发给你!



    接下来是对各位想要学习java的朋友的一些小小建议,希望对你有帮助!

    1、 千万别自己一个人闭门造车。

    不要认为自己可以解决所有问题,学习编程很抽象,尤其是在刚开始学的时候,很多时候你是无从下手的,所以我建议大家一定要懂得借力,找一些学的比较好的同学,或者你认识的朋友带带你,有人真的是事半功倍,效率会提高非常多。或者加一些学习氛围不错的Java交流学习群(我这里有),跟有经验的人交流可以学到很多好的学习方法和技巧,提高我们的学习效率。

    2、 工欲利其事,必先利其器。

    在确定了要学习Java前,你一定要有一个非常完整的Java技术栈的大纲体系(比如下面的学习路线图)以及还不错的学习教程,如果我们连一套完整的学习教程都没有,根本不可能学会Java。而很多人在开始时用的教程非常老,很多技术都已经过时,企业并不用这些技术,所以学了也是白耽误工夫。如果大家找不到合适的Java教程,可以试试我推荐的教程,都是免费的,不需要担心。

    Java300集零基础适合初学者视频教程_Java初学入门视频基础巩固教程​

    图标

    3、 实践是检验真理的唯一标准。

    学习编程一定要记得多动手写代码,视频只需要看一两遍即可。有很多同学不懂得如何学习编程,盲目无脑的一直刷视频看,但你看完视频后很快就会忘记,其实是在浪费你的时间。学习编程的主要目的是能做出好的互联网软件产品。这是一个需要动手的工作,所以我们学编程一定要注重动手写代码。而很多人学习编程都是只看视频,这样的学习方式是非常错误的,所以大家对于这点一定要牢记在心。

    4、 项目作品是展现我们水平的重要因素。

    我们在学完一个阶段后,一定要记得针对这个阶段去完成一个项目实战。真正能让我们印象深刻,加深理解的学习方式就是参与到项目的开发中。项目才能检验我们这个阶段到底学的怎么样,所以大家在学习的过程中切记项目的重要性,很多人学习Java最后却不能独立完成一个项目模块,如果你达不到这个水平,那么你是不可能找到Java开发工作的。

    史上最全java项目实战课程(含项目实战+源码)​

    图标

    我认为新手在学习Java的过程中常见的误区:

    1.没有详细系统的学习规划,越学越迷茫,不知道应该往哪里走,特别有想放弃的想法。

    2.学习的技术并不是现在企业需要的技术,跟不上时代,不具备竞争力。

    3.学习效率非常低,遇到一个小问题解决起来很费时间,甚至有的时候会卡几个小时,导致信心受挫,对自己适不适合产生怀疑。

    4.没有掌握学习Java的方法和技巧,导致走的弯路特别多,钻进程序的死胡同出不来。

    如果你也有以上的学习困惑,觉得自己无从下手,学习的效率很低,学了后面就把前面的忘记这些问题,基本都是因为自己的学习方法不对。所以我建议你一定要找有经验的人多沟通,这些问题都是可以得到很好解决的。

    几个小技巧大家参考一下:

    1、基础很重要,不要盲目的追求新技术,往往决定着你思维深度而又被你忽略的就是你的基础!

    2、多动手敲代码,有时电脑就和女(男)朋友一样,它和你想的总是有差异的!

    3、多百度,多搜索,百度会帮你解决掉百分之九十以上的问题!

    4、多思考,急于动手写代码是大忌,熬夜写代码效率并不高。

    希望我的学习经验可以帮助到你,多结交一个圈子内的大佬,方便以后创业,毕竟一辈子给人打工是没有止境的。

    文章整理不易,还请各位抬抬您的小贵手,点个赞呗~

    展开全文
  • Java Web安全之代码审计

    千次阅读 2019-02-13 09:14:00
    本文内容主要以Java Web安全-代码审计为中心展开。 一、JavaWeb 安全基础 1. 何为代码审计? 通俗的说Java代码审计就是通过审计Java代码来发现Java应用程序自身中存在的安全问题,由于Java本身是编译型语言,所以...

    信息安全的75%发生在Web应用而非网络层。本文内容主要以Java Web安全-代码审计为中心展开。

    一、JavaWeb 安全基础

    1. 何为代码审计?

    通俗的说Java代码审计就是通过审计Java代码来发现Java应用程序自身中存在的安全问题,由于Java本身是编译型语言,所以即便只有class文件的情况下我们依然可以对Java代码进行审计。对于未编译的Java源代码文件我们可以直接阅读其源码,而对于已编译的class或者jar文件我们就需要进行反编译了。

    Java代码审计其本身并无多大难度,只要熟练掌握审计流程和常见的漏洞审计技巧就可比较轻松的完成代码审计工作了。但是Java代码审计的方式绝不仅仅是使用某款审计工具扫描一下整个Java项目代码就可以完事了,一些业务逻辑和程序架构复杂的系统代码审计就非常需要审计者掌握一定的Java基础并具有具有一定的审计经验、技巧甚至是对Java架构有较深入的理解和实践才能更加深入的发现安全问题。

    本文将分为多章节来讲述Java代码审计需要掌握的前置知识以及Java代码审计的流程、技巧。

    2. 准备环境和辅助工具

    在开始Java代码审计前请自行安装好Java开发环境,建议使用MacOS、Ubuntu操作系统。

    所谓“工欲善其事,必先利其器”,合理的使用一些辅助工具可以极大的提供我们的代码审计的效率和质量!

    强烈推荐下列辅助工具:

    1.Jetbrains IDEA(IDE)

    2.Sublime text(文本编辑器)

    3.JD-GUI(反编译)

    4.Fernflower(反编译)

    5.Bytecode-Viewer

    6.Eclipse(IDE)

    7.NetBeans(IDE)

    二、反编译技巧

    在渗透测试的时候需要审计的代码通常是class文件或者jar包,那么我们应该如何审计呢?让我们先来学习一下什么是Java源码和字节码。

    1. Java类编译与反编译基础

    简单的说Java源码就是未经编译的.java文件,我们可以很轻松的阅读其中的代码逻辑,而字节码.class文件则是.java文件经过编译之后产生的字节码文件,因为.class文件是编译后的二进制文件所以我们是无法直接阅读的,只能通过反编译工具将二进制文件转换成java代码或者ASM代码。

    示例代码Test.java:

    /**
     * @author yz
     */
    public class Test {
    
    	public static void hello() {
    		System.out.println("Hello~");
    	}
    
    	public void world() {
    		System.out.println("World!");
    	}
    
    	public static void main(String[] args) {
    		hello();
    	}
    
    }

    Test.java编译执行流程:

    Test.java 源码、字节码

    由于class文件的可读性较差,通常我们需要使用Java反编译工具来反编译代码。我们通常会使用到JD-GUI、IDEA Fernflower插件、Bytecode-Viewer、Fernflower、JAD、JBE、JEB 等工具来反编译class。

    其中JD-GUI可能是目前反编译中使用的最多的工具了,但是个人觉得JD-GUI的反编译能力远不如经过IDEA(IDEA应该是使用的改版后的Fernflower),因为IDEA默认支持对jar和class的反编译,所以我个人强烈推荐使用IDEA来反编译class代码。

    当然,反编译工具很多时候也不是万能的,JD-GUI经常遇到无法反编译或反编译过程中程序直接崩溃的情况,遇到这类情况我们通常可以使用IDEA反编译试试,如果IDEA也无法反编译可以使用JBE来加载class文件读取程序的字节码,如果JBE仍无法读取类信息还可以使用JDK自带的javap命令来读取class类字节码,如果上诉所有的方法都无法反编译,那么恐怕是这个类本身就存在无法编译问题要么可能就是类文件被加密处理过。可能你会说java编译的class不是说不可以加密吗?没错,这里所说的加密其实是为了保护编译后的class代码不可反编译,通过实现自定义ClassLoader来loadClass加密后的类方式而已,这种加密方式曾在实战中也有遇到。

    2. 反编译整个Jar技巧

    通常我们在某些特殊的场景下拿到的只是jar文件,那么我们应该如何反编译整个jar包的class文件呢?

    2.1. Fernflower

    Fernflower可以很轻松的实现jar的完整反编译,执行如下命令即可: java -jar fernflower.jar jarToDecompile.jar decomp/ 其中jarToDecompile.jar是需要反编译的jar文件,decomp是反编译后的class文件所存放的目录。需要注意的是Fernflower如遇无法反编译的情况可能会生成空的java文件!

    2.2. JD-GUI

    JD-GUI是一个带GUI的反编译工具,在JD-GUI的菜单中点击File–>Save All Sources即可反编译jar。

    2.3. IDEA

    IDEA默认就支持jar包反编译,同时还支持class文件名(⇧⌘F)、类方法名称(⇧⌘O)搜索。

    2.4. Bytecode-Viewer

    FernFlower提供了GUI版本Bytecode-Viewer,Bytecode-Viewer提供了直接反编译的class、jar、zip、apk、dex功能,直接拖拽jar就可以直接对整个jar进行反编译了。

    2.5. Find命令

    find命令并不能支持Java反编译,但是find命令可以非常方便的搜索经过编译后的二进制文件中的内容,所以有的时候使用find命令通常是最简单实用的,直接解压jar包然后使用find命令搜索: find ./ -type f -name “*.class” |xargs grep XXXX 即可搞定。

    2.6 使用Find命令和Fernflower实现批量反编译jar

    当我们只有项目war包且源码经过打包后发布到WEB-INF/lib的情况下,我们不得不去找出待审计源码的具体jar文件并反编译。遇到这种情况我们可以巧妙的使用find命令来反编译所有目标的jar包。

    这里以jcms的一个非常老版本为例,jcms最终给客户部署的war包中源码并不是在WEB-INF/classes目录下,而是将整个jcms系统按模块打包成了多个jar包放在了WEB-INF/lib目录下。我们可以通过搜索com.hanweb包名称来找出所有jar中包含了jcms的文件并通过Fernflower来反编译。

    java -jar /Users/yz/Desktop/javaweb-decomplier/javaweb-decomplier.jar -dgs=1 $(find /Users/yz/Desktop/jcms/WEB-INF/lib/ -type f -name "*.jar" |xargs grep "com.hanweb" |awk '{print $3}') /Users/yz/jcms-decomplier

    依赖的jar: javaweb-decomplier、Intellij java-decompiler。

    执行上面的命令后会在jcms-decomplier目录下看到所有的jar已经被Fernflower反编译了。

    3. IntelliJ IDEA 推荐

    IntelliJ IDEA是Jetbrains出品的一款非常强大的Java IDE,IDEA提供了强大的代码搜索、近乎完美的反编译、动态调试等功能可以最大程度的辅助我们代码审计。

    不可以否认,与IDEA相比虽然Eclipse和Netbeans也有与之类似的功能,但是在真正的实战体验中个人更倾向于使用IDEA,虽然曾经的我也是一个重度Eclipse开发者。

    三、IDEA代码搜索技巧

    IDEA的搜索快捷键是:⇧⌘F,使用IDEA提供的搜索功能可以非常快速的定位漏洞点信息。

    IDEA可以通过自定义搜索范围来精确查找我们需要审计的代码。默认搜索的是所有的位置,不过我们可以点击红色箭头指向的…按钮来细化我们的搜索范围。

    1. 自定义范围搜索

    自定义搜索范围示例:

    自定义搜索范围后就可以在搜索时使用自定义的配置进行范围搜索了,有助于我们在挖漏洞的时候缩小代码定位范围。

    2. 标记搜索

    搜索快捷键: ⌘O,标记搜索支持类名、方法名搜索(包括class或jar文件中的方法也支持搜索)。

    3. Java调用链搜索

    当我们审计代码的时候发现某个方法或类有漏洞时我们需要定位到漏洞的请求地址(触发点),复杂业务系统往往会让我们很难定位到漏洞的触发点。借助IDEA的方法调用链搜索功能就可以很轻松的找出方法的调用链和触发点。

    选择类或者方法名–>右键–>Find Useages或者使用快捷键⌥F7

    四、Java Web基础

    1. Java分层思想

    为了更好的管理项目我们通常会采用分层架构的方式来开发Java Web项目,分层设计的好处在于可以非常方便的分清楚包之间的业务逻辑关系。

    常见的JavaWeb项目分层:

    视图层(View 视图)

    控制层(Controller、Action 控制层)

    服务层(Service)

    业务逻辑层BO(business object)  

    实体层(entity 实体对象、VO(value object) 值对象 、模型层(bean)。

    持久层(dao- Data Access Object 数据访问层、PO(persistant object) 持久对象)

    基于Java分层架构的示例项目:

    3. 什么是Servlet?

    Servlet是在Java Web容器上运行的小程序,通常我们用Servlet来处理一些较为复杂的服务器端的业务逻辑。值得注意的是在Servlet3.0之后(Tomcat7+)可以使用注解方式配置Servlet了。

    基于注解的Servlet

    Servlet3.0之前的版本都需要在web.xml中配置,Servlet是两对标签,由<servlet>和<servlet-mapping>组成,Spring MVC框架就是基于Servlet技术实现的。

    基于配置实现的Servlet

    HttpServlet类

    实现一个Servlet很简单,只需要继承javax.servlet.http.HttpServlet类并重写doXXX方法或者service方法就可以了,其中需要注意的是重写HttpServlet类的service方法可以获取到上述七种Http请求方法的请求。

    4. JSP、Servlet之间的关系

    JSP、JSPX文件是可以直接被Java容器直接解析的动态脚本,jsp和其他脚本语言无异,不但可以用于页面数据展示,也可以用来处理后端业务逻辑。

    从本质上说JSP就是一个Servlet,因为jsp文件最终会被编译成class文件,而这个Class文件实际上就是一个特殊的Servlet。

    JSP文件会被编译成一个java类文件,如index.jsp在Tomcat中Jasper编译后会生成index_jsp.java和index_jsp.class两个文件。而index_jsp.java 继承于HttpJspBase类,HttpJspBase是一个实现了HttpJspPage接口并继承了HttpServlet的标准的Servlet,__jspService方法其实是HttpJspPage接口方法,类似于Servlet中的service方法,这里的__jspService方法其实就是HttpJspBase的service方法调用。

    5. 什么是Filter

    Filter是JavaWeb中的过滤器,用于过滤URL请求。通过Filter我们可以实现URL请求资源权限验证、用户登陆检测等功能。Filter是一个接口,实现一个Filter只需要重写init、doFilter、destroy方法即可,其中过滤逻辑都在doFilter方法中实现。

    Filter和Servlet一样是Java Web中最为核心的部分,使用Servlet和Filter可以实现后端接口开发和权限控制,当然使用Filter机制也可以实现MVC框架,Struts2实现机制就是使用的Filter。

    Filter的配置类似于Servlet,由<filter>和<filter-mapping>两组标签组成,如果Servlet版本大于3.0同样可以使用注解的方式配置Filter。

    6. Filter和Servlet的总结

    对于基于Filter和Servlet实现的简单架构项目,代码审计的重心集中于找出所有的Filter分析其过滤规则,找出是否有做全局的安全过滤、敏感的URL地址是否有做权限校验并尝试绕过Filter过滤。第二点则是找出所有的Servlet,分析Servlet的业务是否存在安全问题,如果存在安全问题是否可以利用?是否有权限访问?利用时是否被Filter过滤等问题,切勿看到Servlet、JSP中的漏洞点就妄下定论,不要忘了Servlet前面很有可能存在一个全局安全过滤的Filter。

    Filter和Servlet都是Java Web提供的API,简单的总结了下有如下共同点。

     1.Filter和Servlet都需要在web.xml或注解(@WebFilter、@WebServlet)中配置,而且配置方式是非常的相似的;

      2.Filter和Servlet都可以处理来自Http请求的请求,两者都有request、response对象;

      3.Filter和Servlet基础概念不一样,Servlet定义是容器端小程序,用于直接处理后端业务逻辑,而Filter的思想则是实现对Java Web请求资源的拦截过滤;

      4.Filter和Servlet虽然概念上不太一样,但都可以处理Http请求,都可以用来实现MVC控制器(Struts2和Spring框架分别基于Filter和Servlet技术实现的);

      5.一般来说Filter通常配置在MVC、Servlet和JSP请求前面,常用于后端权限控制、统一的Http请求参数过滤(统一的XSS、SQL注入、Struts2命令执行等攻击检测处理)处理,其核心主要体现在请求过滤上,而Servlet更多的是用来处理后端业务请求上

    7. 初识JavaWeb MVC框架

    传统的开发存在结构混乱易用性差耦合度高可维护性差等多种问题,为了解决这些毛病分层思想和MVC框架就出现了。MVC即模型(Model)、视图(View)、控制器(Controller), MVC模式的目的就是实现Web系统的职能分工。

    截至2018年底,绝大多数的新项目都已然改为了基于Spring Boot的Spring MVC实现,也就是说曾经站在JavaWeb MVC最巅峰的Struts2框架已经逐渐陨落。

    7.1 Spring MVC 控制器

    在Spring进入了3.0时代,使用Java注解的方式也逐渐的流行了起来,曾经写一个Spring的控制器我们通常要在xml中声明Spring bean并配置处理的URL,而在新时代的Spring项目中我们通常用Spring MVC注解就可以轻松完成Spring MVC的配置了。

    一个基于Spring 注解配置的控制器:

    package org.javaweb.codereview.controller;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    @Controller
    public class IndexController {
    @RequestMapping("/index.php")
    public String index() {
    return "/index.html";
    }}

    Spring Controller注解:

    @Controller

    @RestController

    @RepositoryRestController

    Spring MVC请求配置注解:

    @RequestMapping

    @GetMapping

    @PostMapping

    @PutMapping

    @DeleteMapping

    @PatchMapping

    Spring MVC除了上述6种Http请求处理注解以外还有Spring Data JPA Rest提供的特殊的@RepositoryRestResource注解,@RepositoryRestResource是基于Spring Data JPA REST库实现的,Spring Data JPA REST提供的API可支持通过JPA查询数据并处理Http请求服务。

    基于XML配置的Spring MVC

    对于一些老旧的项目可能还保留了一些基于xml配置的方式Spring MVC项目,这里只简单的介绍下如何配置不做过多的描述。基于配置方式的控制器一般是在Controller类中实现了Spring的org.springframework.web.servlet.mvc.Controller接口的handleRequest方法(当然还有其他途径,如:AbstractCommandController和SimpleFormController但都已经过时了)。

    TestController.java示例代码:

    package org.javaweb.codereview.controller;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    /**
     * @author yz
     */
    public class TestController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("index");
    return mv;
    }
    }

    XML配置具体的bean

    <bean name="/test.do" class="org.javaweb.codereview.controller.TestController"/>

    7.2 Struts2控制器

    Struts2主要的开发模式是基于xml配置,在struts.xml中配置Action地址和对应的处理类。

    不过Struts2(2.1.6版本开始)也可以使用struts2-convention-plugin插件来实现基于注解方式的配置。

    需要注意的是Struts2的参数是可以通过get/set方法传入的,如上图TestActionAnnotation类的username变量是可以直接在Http请求中的URL传入的。

    7.3 快速找出Http请求请求URL

    代码审计中我们可以选择优先从Controller、Servlet和JSP中入手,也可以选择从漏洞点反向推出Http请求的入口地址,这里将讲解下如何快速找到这些请求入口,因为Struts2和Spring MVC的原理比较接近,所以本节只以Spring MVC为例。

    7.3.1 查找Spring MVC所有的控制器

    如果有源码的情况下可以使用find命令或者IDEA的全局搜索功能即可快速搜索到所有的控制器,如果只有class文件的情况下可以使用find命令:

    find ~/cms/ -type f -name "*.class" |xargs grep -E "Controller|@RestController|RepositoryRestController"

    7.3.2 查找所有的请求处理URL

    查找请求处理URL的方式同理,使用如下find命令查找所有class中的请求处理注解:

    find ~/cms/ -type f -name "*.class" |xargs grep -E "RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RepositoryRestResource"

    7.4 Spring MVC和Struts2控制器小结

    这一小节我们只是简单的介绍下Spring MVC和Struts2的控制器,在后面的框架服务章节将会详细介绍。至于如何去快速定位Struts2的action请自行参考Spring MVC的Controller查找方式这里不再讲解。

    五、Java语言的动态性

    Java语言动态性一直以来都比较差,并不像PHP那样灵活。在Java中的动态性往往需要使用一些曲折的方式来实现.这里简单列举了Java十余种动态性相关技术并总结部分技术实现安全问题。

    1.Java反射机制

    2.MethodHandle

    3.JDK动态代理

    4.使用JVM上的动态语言(如:Groovy、JRuby、Jython)

    5.表达式库(如:OGNL、MVEL、SpEL、EL)

    6.JSP、JSPX、Quercus(Resin容器提供了PHP5支持)

    7.字节码库(如:Asm、Javassist、Cglib、BCEL)

    8.ScriptEngineManager(脚本引擎)。

    9.动态编译(如:JDT、JavaCompiler)

    10.ClassLoader、URLClassLoader

    11.模版引擎(如:Freemarker、Velocity)

    12.序列化、反序列化(包含Java 对象序列化、XML、JSON等)

    13.JNI、JNA(Java调用C/C++)

    14.OSGi(Open Service Gateway Initiative)

    15.RMI(Java远程方法调用,基于对象序列化机制实现)

    16.WebService

    17.JDWP(Java Platform Debugger Architecture Java调试协议)

    18.JMX(Java Management Extensions)

    1. Java反射机制特性

    Java反射机制可以无视类方法、变量访问权限修饰符,可以调用任何类的任意方法、访问并修改成员变量值。也就是说只要发现一处Java反射调用漏洞几乎就可以为所欲为了。当然前提可能需要你能控制反射的类名、方法名和参数。

    一行代码即可实现反射调用Runtime执行本地命令:

    Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "whoami")

    获取一个类的对象(如Runtime类)我们一般会采用如下几种方式:

      1.Class.forName(“java.lang.Runtime”)、”".getClass().forName(“java.lang.Runtime”)

      2.Runtime.class

      3.ClassLoader.getSystemClassLoader().loadClass(“java.lang.Runtime”)

    Java反射获取类方法有两种方式:

      1.getMethod(xxx),getMethods()

      2.getDeclaredMethod(xxx)、getDeclaredMethods()。

    区别在于getMethod会返回当前类和父类的所有public方法,而getDeclaredMethod返回的是当前的所有方法。

    Java反射获取类成员变量有两种方式:

      1.getField(xxx)、getFields()

      2.getDeclaredField(xxx)、getDeclaredFields()

    getField和getDeclaredField区别同上,如果想要调用private修饰的Field或者Method只需要设置下setAccessible为true就可以了,如:xxxMethod.setAccessible(true)。

    Java的大部分框架都是采用了反射机制来实现的(如:Spring MVC、ORM框架等),所以我们不得不掌握Java反射机制来提升我们的代码审计能力。

    Java反射机制实现无关键字执行命令

     

    import java.io.InputStream;
    import java.lang.reflect.Method;
    import java.util.Scanner;
    /**
     * @author yz
     */
    public class ReflectionTest {
    public static void exec() {
    try {
    System.out.println(Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "curl -i localhost:8000"));
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    try {
    String str = "whoami";
    // java.lang.Runtime
    String runtime = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101});
    // Runtime.class
    Class<?> c = Class.forName(runtime);
    // 获取getRuntime方法,Runtime.getRuntime()
    Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));
    // 获取Runtime的exec方法,rt.exec(xxx)
    Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);
    // Runtime.getRuntime().exec(str)
    Object obj2 = m2.invoke(m1.invoke(null), str);
    // 获取命令执行结果Process类的getInputStream()方法
    Method m = obj2.getClass().getMethod(new String(new byte[]{103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109}));
    m.setAccessible(true);
    // process.getInputStream()
    InputStream in = (InputStream) m.invoke(obj2, new Object[]{});
    // 输出InputStream内容到
    Scanner scanner = new Scanner(in).useDelimiter("\\A");
    System.out.println(scanner.hasNext() ? scanner.next() : "");
    } catch (Throwable t) {
    t.printStackTrace();
    }
    }
    }

    2. JDK7+ MethodHandle

    JDK7开始Java提供了MethodHandle可以非常方便的访问和调用类方法,MethodHandle的能力和Java反射机制相似,但效率却远高出Java反射机制,但MethodHandle也并不是那么完美的,缺点是MethodHandle必须要求JDK版本大于等于1.7,MethodHandle也无法像反射那样调用私有方法和变量。

    参考:通过代码简单介绍JDK 7的MethodHandle,并与.NET的委托对比

    基于MethodHandle实现的调用Runtime执行系统命令

    import java.io.InputStream;
    import java.lang.invoke.MethodHandle;
    import java.lang.invoke.MethodHandles;
    import java.lang.invoke.MethodType;
    import java.util.Scanner;
    /**
     * @author yz
     */
    public class MethodHandlesTest {
    public static void main(String[] args) {
    try {
    String               str          = "ping p2j.cn -c 1";
    Class                runtimeClass = Runtime.class;
    MethodHandles.Lookup lookup       = MethodHandles.lookup();
    // Runtime rt = Runtime.getRuntime()
    MethodHandle methodHandle = lookup.findStatic(
    runtimeClass, "getRuntime", MethodType.methodType(runtimeClass)
    );
    // 获取Runtime的exec方法
    MethodHandle execMethod = lookup.findVirtual(
    runtimeClass, "exec", MethodType.methodType(Process.class, new Class[]{
    String.class
    })
    );
    // 获取Process的getInputStream方法
    MethodHandle inputStreamMethod = lookup.findVirtual(
    Process.class, "getInputStream", MethodType.methodType(InputStream.class)
    );
    // 调用Runtime.getRuntime().exec(xxx).getInputStream()
    InputStream in = (InputStream) inputStreamMethod.invoke(
    execMethod.invoke(methodHandle.invoke(), str)
    );
    // 输出InputStream内容到
    Scanner scanner = new Scanner(in).useDelimiter("\\A");
    System.out.println(scanner.hasNext() ? scanner.next() : "");
    } catch (Throwable t) {
    t.printStackTrace();
    }
    }
    }

    六、Java代码审计-Checklist

    通常我喜欢把代码审计的方向分为业务层安全问题、代码实现和服务架构安全问题,。

    1. 业务层安全常见问题

    业务层的安全问题集中在业务逻辑和越权问题上,我们在代码审计的过程中尽可能的去理解系统的业务流程以便于发现隐藏在业务中的安全问题。

    1.1 业务层中常见的安全问题Checklist

    1.用户登陆、用户注册、找回密码等功能中密码信息未采用加密算法。

    2.用户登陆、用户注册、找回密码等功能中未采用验证码或验证码未做安全刷新(未刷新Session中验证码的值)导致的撞库、密码爆破漏洞。

    3.找回密码逻辑问题(如:可直接跳过验证逻辑直接发包修改)。

    4.手机、邮箱验证、找回密码等涉及到动态验证码等功能未限制验证码失败次数、验证码有效期、验证码长度过短导致的验证码爆破问题。

    5.充值、付款等功能调用了第三方支付系统未正确校验接口(如:1分钱买IPhone X)。

    6.后端采用了ORM框架更新操作时因处理不当导致可以更新用户表任意字段(如:用户注册、用户个人资料修改时可以直接创建管理员账号或其他越权修改操作)。

    7.后端采用了ORM框架查询数据时因处理不当导致可以接收任何参数导致的越权查询、敏感信息查询等安全问题。

    8.用户中心转账、修改个人资料、密码、退出登陆等功能未采用验证码或Token机制导致存在CSRF漏洞。

    9.后端服务过于信任前端,重要的参数和业务逻辑只做了前端验证(如:文件上传功能的文件类型只在JS中验证、后端不从Session中获取用户ID、用户名而是直接接收客户端请求的参数导致的越权问题)。

    10.用户身份信息认证逻辑问题(如:后台系统自动登陆时直接读取Cookie中的用户名、用户权限不做验证)。

    11.重要接口采用ID自增、ID可预测并且云端未验证参数有效性导致的越权访问、信息泄漏问题(如:任意用户订单越权访问)。

    12.条件竞争问题,某些关键业务(如:用户转账)不支持并发、分布式部署时不支持锁的操作等。

    13.重要接口未限制请求频率,导致短信、邮件、电话、私信等信息轰炸。

    14.敏感信息未保护,如Cookie中直接存储用户密码等重要信息。

    15.弱加密算法、弱密钥,如勿把Base64当成数据加密方式、重要算法密钥采用弱口令如123456。

    16.后端无异常处理机制、未自定义50X错误页面,服务器异常导致敏感信息泄漏(如:数据库信息、网站绝对路径等)。

    17.使用DWR框架开发时前后端不分漏洞(如:DWR直接调用数据库信息把用户登陆逻辑直接放到了前端来做)。

    2. 代码实现常见问题

    代码审计的核心是寻找代码中程序实现的安全问题,通常我们会把代码审计的重心放在SQL注入、文件上传、命令执行、任意文件读写等直接威胁到服务器安全的漏洞上,因为这一类的漏洞杀伤力极大也是最为致命的。

    ###2.1 代码实现中常见的安全问题Checklist

      1.任意文件读写(文件上传、文件下载)、文件遍历、文件删除、文件重命名等漏洞

      2.SQL注入漏洞

      3.XXE(XML实体注入攻击)

      4.表达式执行(SpEL、OGNL、MVEL2、EL等)

      5.系统命令执行漏洞(ProcessBuilder)

      6.反序列化攻击(ObjectInputStream、JSON、XML等)

      7.Java反射攻击

      8.SSRF攻击

    2.1.1 Java 文件名空字节截断漏洞(%00 Null Bytes)

    空字节截断漏洞漏洞在诸多编程语言中都存在,究其根本是Java在调用文件系统(C实现)读写文件时导致的漏洞,并不是Java本身的安全问题。不过好在高版本的JDK在处理文件时已经把空字节文件名进行了安全检测处理。

    2013年9月10日发布的Java SE 7 Update 40修复了空字节截断这个历史遗留问题。此次更新在java.io.File类中添加了一个isInvalid方法,专门检测文件名中是否包含了空字节。

    修复的JDK版本所有跟文件名相关的操作都调用了isInvalid方法检测,防止空字节截断。

    修复前(Java SE 7 Update 25)和修复后(Java SE 7 Update 40)的对比会发现Java SE 7 Update 25中的java.io.File类中并未添加\u0000的检测。

    受空字节截断影响的JDK版本范围:JDK<1.7.40,单是JDK7于2011年07月28日发布至2013年09月10日发表Java SE 7 Update 40这两年多期间受影响的就有16个版本,值得注意的是JDK1.6虽然JDK7修复之后发布了数十个版本,但是并没有任何一个版本修复过这个问题,而JDK8发布时间在JDK7修复以后所以并不受此漏洞影响。

    参考:

    JDK-8014846 : File and other classes in java.io do not handle embedded nulls properly

    维基百科-Java版本歷史

    Oracle Java 历史版本下载

    2.1.2 测试Java写文件截断测试

    测试类FileNullBytes.java:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    /**
     * @author yz
     */
    public class FileNullBytes {
    public static void main(String[] args) {
    try {
    String fileName = "/tmp/null-bytes.txt\u0000.jpg";
    FileOutputStream fos = new FileOutputStream(new File(fileName));
    fos.write("Test".getBytes());
    fos.flush();
    fos.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    使用JDK1.7.0.25测试成功截断文件名:

    使用JDK1.7.0.80测试写文件截断时抛出java.io.FileNotFoundException: Invalid file path异常:

    空字节截断利用场景

    Java空字节截断利用场景最常见的利用场景就是文件上传时后端使用了endWith、正则使用如:.(jpg|png|gif)$验证文件名后缀且文件名最终原样保存,同理文件删除(delete)、获取文件路径(getCanonicalPath)、创建文件(createNewFile)、文件重命名(renameTo)等方法也可适用。

    空字节截断修复方案

    最简单直接的方式就是升级JDK,如果担心升级JDK出现兼容性问题可在文件操作时检测下文件名中是否包含空字节,如JDK的修复方式:fileName.indexOf(‘\u0000′)即可。

    2.1.2 任意文件读取漏洞

    任意文件读取漏洞即因为没有验证请求的资源文件是否合法导致的,此类漏洞在Java中有着较高的几率出现,任意文件读取漏洞看似很简单,但是在这个问题上翻车的有不乏一些知名的中间件:Weblogic、Tomcat、Resin又或者是主流MVC框架:Spring MVC、Struts2。所以在审计文件读取功能的时候要非常仔细,或许很容易就会有意想不到的收获!

    任意文件读取示例代码file-read.jsp:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page import="java.io.ByteArrayOutputStream" %>
    <%@ page import="java.io.File" %>
    <%@ page import="java.io.FileInputStream" %>
    <%
        File file = new File(request.getParameter("path"));
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int a = -1;
        while ((a = fis.read(b)) != -1) {
            baos.write(b, 0, a);
        }
        out.write("<pre>" + new String(baos.toByteArray()) + "</pre>");
        fis.close();
    %>

    访问file-read.jsp文件即可读取任意文件:http://localhost:8080/file/file-read.jsp?path=/etc/passwd

    快速发现这类漏洞得方式其实也是非常简单的,在IDEA中的项目中重点搜下如下文件读取的类。

      1.JDK原始的java.io.FileInputStream类

      2.JDK原始的java.io.RandomAccessFile类

      3.Apache Commons IO提供的org.apache.commons.io.FileUtils类

      4.JDK1.7新增的基于NIO非阻塞异步读取文件的java.nio.channels.AsynchronousFileChannel类。

      5.JDK1.7新增的基于NIO读取文件的java.nio.file.Files类。常用方法如:Files.readAllBytes、Files.readAllLines

    如果仍没有什么发现可以搜索一下FileUtil很有可能用户会封装文件操作的工具类。

    Java WebSevice

    Web Service是一种基于SOAP协议实现的跨语言Web服务调用,在Java中Web Service有如下技术实现:Oracle JWS、Apache Axis1、2、XFire、Apache CXF、JBossWS。

    Axis1.4 配置

    web.xml配置Axis1.4

    配置server-config.wsdd文件注册Web Service服务类和方法:

    FileService类,提供了文件读写接口:

    使用IDEA创建Web Service项目默认会创建管理Web Service的API:/servlet/AxisServlet、/services、SOAPMonitor、/servlet/AdminServlet,*.jws以及用监控Web Service的端口5001或5101。

    访问Web Service的FileService服务加上?wsdl参数可以看到FileService提供的服务方法和具体的参数信息。

    使用SOAP-UI调用Web Service接口示例:

    需要注意的是Web Service也是可以设置授权认证的,如实现了WS-Security的WSS4J。

    使用IDEA根据wsdl生成Web Service客户端代码:

    设置wsdl地址、包名:

    新建FileServiceTest类测试接口调用:

    package org.javaweb.codereview.axis.client;
    import java.net.URL;
    /**
     * 文件Web Service服务测试
     *
     * @author yz
     */
    public class FileServiceTest {
    public static void main(String[] args) {
    try {
    FileServiceService         fileService   = new FileServiceServiceLocator();
    URL                        webServiceUrl = new URL("http://localhost:8080/services/FileService");
    FileServiceSoapBindingStub soapService   = new FileServiceSoapBindingStub(webServiceUrl, fileService);
    String content = soapService.readFile("/etc/passwd");
    System.out.println(content);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    参考:

    Axis1.4框架 实现webservice服务器和客户端

    使用IDEA根据wsdl生成WebServices客户端代码-Java

    axis2 利用小工具cat.aar

    转自:freebuf

    展开全文
  • JAVA Web技术及应用》读书笔记

    千次阅读 2018-08-29 15:30:00
    第一章 JAVA Web 入门 1.1 Web应用概述 Web应用是一种通过互联网访问的应用程序,使用网页语言编写,通过浏览器运行的动静态网站。 动态网站
  • 200105-SpringBoot 系列 web 篇之自定义返回 Http Code 的 n 种姿势 虽然 http 的提供了一整套完整、定义明确的状态码,但实际的业务支持中,后端并不总会遵守这套规则,更多的是在返回结果中,加一个 code 字段...
  • Java Web常见面试题

    千次阅读 2012-06-30 12:01:11
    学习了MLDN李兴华老师的java web常见面试题的教程,现记录下来和大家分享一下,希望可以对将要面试的童鞋们有所帮助! 1.JSP有哪些内置对象?作用分别是什么? 一共有九个内置对象 pageContext javax.servlet.jsp...
  • WEB开发的相关知识WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源。 Internet上供外界访问的Web资源分为: 静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变的...
  • 文章目录问题一.安全性问题层次关系二.安全性问题的本质三.安全漏洞及处理方式1、SQL注入攻击2、XSS跨站脚本攻击3、CSRF跨站请求伪造漏洞防护...弱口令漏洞10.JSP页面抛出的异常可能暴露程序信息。11.本地缓存漏洞1...
  • 日历表格面板 [ConfigLine.java] 控制条类 [RoundBox.java] 限定选择控件 [MonthMaker.java] 月份表算法类 [Pallet.java] 调色板,统一配色类 Java扫雷源码 Java生成自定义控件源代码 2个目标文件 Java实现HTTP连接...
  • 对于 Java 工程师而言,合理地处理异常是一种基本而重要的能力,然而,在近来的面试中,笔者发现很多应聘者对异常处理的内在原理几无了解,现场手写的异常处理代码也极为“原始”。 鉴于此,笔者将通过本场 Chat 为...
  • Java EE项目中异常设计及处理总结

    千次阅读 2016-12-12 16:24:10
    异常设计 0.J2EE中的异常设计 3层结构 Dao,Service,Controller 异常处理原则: 应该在Controller控制转发之前尽量处理,同时记录log日志,然后在页面以友好的错误提示告诉用户出错了 eg: //创建日志...
  • Java必备常见单词

    万次阅读 多人点赞 2018-04-22 17:36:22
    资源共享学习交流群号:769674658(快满...(一)Java 基础 public 公有的 private 私有的 protected 保护的 ...
  • 10万字208道Java经典面试题总结(附答案)

    万次阅读 多人点赞 2021-08-01 16:05:55
    JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。...
  • java web 加载Spring --web.xml 篇

    万次阅读 2016-12-25 17:40:26
    javaweb中我们首先会遇到的配置文件就是web.xml,这是javaweb为我们封装的逻辑,不在今天的研究中。略过,下面是一个标准的xml配置文件,我们需要的东西就在下面就行添加就行了。 web-app version="3.0" xmlns:...
  • java开发常见错误原因与解决方法

    千次阅读 2018-05-14 14:48:51
    JAVA工程与WEB工程包的区别:一个是asm.jar,一个是jta.jar  java 代码Caused by: java.lang.NoClassDefFoundError: javax/transaction/TransactionManager  缺少spring-framework-2.0.3\lib\j2ee\jta.jar包,版本...
  • Java开发常见英文单词(带音标翻译)

    千次阅读 多人点赞 2020-11-17 17:46:57
    mæt] 格式,样式 ParseException 解析异常 stack [stæk] 堆 trace [treis] 痕迹 printStackTrace order by ['ɔ:də] 按照规则排序 line [lain] 一行 readLine() 读取一行 stream [stri:m] 流 (生活中常见的流有: ...
  • 高性能Java Web 页面静态化技术

    千次阅读 2014-12-03 17:17:45
    package com.yancms.util; import java.io.*; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; /**
  • java常见的英语单词

    万次阅读 多人点赞 2018-08-15 15:33:00
    abstract (关键字) 抽象 ['.bstr.kt]  access vt.访问,存取 ['.kses]‘(n.入口,使用权)  algorithm n.算法 ['.lg.riem]  annotation [java]代码注释 [.n...
  • JAVA业务开发常见错误100例学习笔记

    千次阅读 2020-05-24 11:54:14
    空值处理:分不清楚的null和恼人的空指针 小心 MySQL 中有关 NULL 的三个坑 捕获和处理异常容易犯的错 小心 finally 中的异常 提交线程池的任务出了异常会怎么样? 提交线程池的任务出了异常会怎么样? 日志:日志...
  • Java web 表示层技术

    千次阅读 2017-03-09 13:26:45
    Java web 表示层技术 第一章:java web 工作原理 1.1解析http协议 HTTP是一种超文本传送协议。HTTP是一种无状态的协议,意思是指在web浏览器和web服务器之间不需要建立持久的连接。HTTP遵循请求/响应模型。 ...
  • 1.需要在web.xml中配置相关信息[html] view plain copy error-page> error-code>403error-code> location>/403.htmllocation> error-page> error-page> error-code>404error-code
  • 七、不安全的反序列化 反序列化最严重可导致远程代码执行(RCE,Remote Code Execution),但最常见的反序列化安全问题却是通过修改序列化之后的数据字段,从而进行提权或越权操作。 注:用户登陆后,服务器将用户...
  • Java基础之异常(Exception)

    千次阅读 2018-08-04 10:30:17
    异常,是Java中非常常用的功能,它可以简化代码,并且增强代码的安全性。本文将介绍一些异常高级知识,也是学习Java一来的一次总结。包括以下内内容: 异常的基础知识 异常特点 异常误用 如何正确地使用异常 异常...
  • java开发常见问题总结

    万次阅读 2016-03-30 14:13:47
    Java编程中的一些常见问题汇总 ..本文列举了我在周围同事的Java代码中看到的一些比较典型的错误。显然,静态代码分析(我们团队用的是qulice)不可能发现所有的问题,这也是为什么我要在这里列出它们的原因。 ...
  • java优化代码常见套路

    万次阅读 多人点赞 2019-12-28 11:32:03
    目录 程序员的痛点(烂代码) 该如何优化代码 前台后台两次md5加盐加密 JSR303和全局异常处理 Redis通用的key生成策略和通用的RedisService方法 程序猿的必读书籍 程序员的痛点(烂代码) 每次做完项目之后,自己想...
  • 这是总结自己在java web开发中的一些经验,写下的同时加深理解吧。。。。
  • Java使用自定义注解优雅地解决异常

    万次阅读 2020-08-29 23:04:05
    我们在实际的开发的过程中是不是经常会遇到这样的情况:当调用服务出现错误的时候页面直接报500的错误,并且在页面显示一大串错误提示,很明显这种异常信息的展示对用户体验是非常不好的,用户更关心服务能不能用,...
  • 本篇文章主要介绍的是SpringBoot非web项目进行全局异常的处理。 SpringBoot版本:2.1.9.RELEASE Mybatis Plus版本:3.3.0 上个项目使用的是SpringBoot+Mybatis Plus+zbus,项目架构是:zbus分为客户端和服务端,...
  • Consider the following segment of Java code, stored in a file called JollyMessage.java: 考虑以下Java代码段,这些段存储在名为JollyMessage.java的文件中: // A jolly message is written to the screen...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,385
精华内容 12,554
关键字:

java web常见异常code

java 订阅