Java EE

Java中SPI机制详解

谁说我不能喝 提交于 2020-12-13 14:03:27
本文转载于 高级开发必须理解的Java中SPI机制 本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践、学习开源项目提供参考。 一、 SPI是什么 SPI全称 Service Provider Interface ,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 整体机制图如下: Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。 系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦。 二、使用场景 概括地说,适用于:调用者根据实际使用需要,启用、扩展、或者替换框架的实现策略。 比较常见的例子: 数据库驱动加载接口实现类的加载 JDBC加载不同类型数据库的驱动 日志门面接口实现类加载 SLF4J加载不同提供商的日志实现类 Spring

getOutputStream() has already been called for this response解释以及解决方法

狂风中的少年 提交于 2020-12-13 12:48:09
异常:getOutputStream() has already been called for this response 的解决方法   今天在第一次接触使用“验证码”功能时,在执行时出现了异常信息:   严重: Servlet.service() for servlet jsp threw exception   java.lang.IllegalStateException: getOutputStream() has already been called for this response   。。。。   在网上搜索之后的解决方法是:   在生成验证码的jsp文件末尾添加两句话   out.clear(); out = pageContext.pushBody();   ===========================================================================   查找的原文如下:   ()   tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法   在tomcat5下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等), 没有妥善处理好的原因。 具体的原因就是

JavaWeb学习之XML

霸气de小男生 提交于 2020-12-13 12:44:43
模拟servlet执行 浏览器的入口不同(访问路径),访问的资源也就不同,如下: 为了灵活的实现不同路径(/hello) 执行不同的资源 ( HeIIoMyServlet) 我们需要使用 XML 进行配置 ; 为了 限定 XML 内容 ,我们需要使用 xml 约束 ( DTD 或 schema) ; 为了 获得 xml 内容 ,我们需要使用 dam4j 进行解析 XML XML 称为 Extensible Markup Language, 意思是 可扩展的标记语言 。 XML 语法上和 HTML 比较相似,但 HTML 中的元素是固定的,而 XML 的标签 是可以由 用户自定义 的。 XML 语法 XML文档声明 1. 文档声明必须为 <?xml开头,以?> 结束 ; 2.文档声明必须从文档的 0行0 列位置开始 : 3. 文档声明只有属性 : a) versioin: 指定 XML 文档版本。必须属性,因为我们不会选择 1.1 ,只会 选择 1.0 ; b) encoding: 指定当前文档的编码。可选属性,默认值是。 utf-8: 元素element 1. 元素是 XML 文档中最重要的组成部分, 2. 普通元素的结构开始标签、元素体、结束标签组成。例如 :<hello> 大家好 </hello> 3. 元素体 : 元素体可以是元素,也可以是文本,例如 :<b><a> 你好 <

【转】 关于IDEA javax.servlet.http.HttpServletRequest; 不存在 解决方案

笑着哭i 提交于 2020-12-13 10:23:21
【转】 关于IDEA javax.servlet.http.HttpServletRequest; 不存在 解决方案 参考文章: (1)【转】 关于IDEA javax.servlet.http.HttpServletRequest; 不存在 解决方案 (2)https://www.cnblogs.com/yft-javaNotes/p/10327561.html 备忘一下。 来源: oschina 链接: https://my.oschina.net/stackoom/blog/4794493

JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)

巧了我就是萌 提交于 2020-12-13 00:08:56
一、 装配Bean概述    关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功能强大。 而在Spring中提供3中方法进行配置。 在xml中显示配置。 在Java接口和类中实现配置 。 隐式Bean的发现机制和自动装配原则 。 在现实工作中,这3中方式都会被用到,并且在学习和工作总常常混合使用,所以需要知道3中方式的优先级,也就是应该怎么选择使用哪种方式去把Bean发布到Spring IoC容器中。 以下是3个使用原则: 1.基于约定优于配置原则,最优先的应该是通过隐式Bean的发现机制和自动装配的原则。这样的好处是减少程序开发则的决定权,简单又不失灵活。 2.在没有办法使用自动装配原则的情况下,应该优先考虑Java接口和类中实现配置,这样的好处就是避免XML配置泛滥,也更为容易。这种场景典型 的例子是一个父类有多个子类。 比如,一个学生类有两个子类,男学生类和女学生类,通过IOC容器初始化一个学生类,容器无法知道使用哪个子类去初始化,这个时候可以使用Java注解配置去指定。 3.在上述方法都无法使用的情况下,那么只能选择XML去配置Spring IoC容器。由于现实工作中常常使用到第三方的类库,有些类不是我们开发的,我们无法修改里面的代码,这个时候

找不到 javax.servlet.http.HttpServletResponse 和 javax.servlet.http.HttpServletRequest 问题解决

空扰寡人 提交于 2020-12-12 23:48:06
找不到 javax.servlet.http.HttpServletResponse 和 javax.servlet.http.HttpServletRequest 问题解决 参考文章: (1)找不到 javax.servlet.http.HttpServletResponse 和 javax.servlet.http.HttpServletRequest 问题解决 (2)https://www.cnblogs.com/yankeshangxing/p/11126044.html 备忘一下。 来源: oschina 链接: https://my.oschina.net/u/4438370/blog/4794353

环境搭建

我们两清 提交于 2020-12-12 18:18:34
创建项目 使用 IDEA 建立一个 Maven 项目。 打开 pom.xml 文件,修改 <packaging>war</packaging> 建立如下目录: 选中项目,点击刷新即可。 加入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.yun</groupId> <artifactId>ssm</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>ssm</name> <description>SpringMVC + Spring + MyBatis</description> <properties> <project.build

Restful api 防止重复提交

梦想的初衷 提交于 2020-12-12 10:31:13
当前很多网站是前后分离的,前端(android,iso,h5)通过restful API 调用 后端服务器,这就存在一个问题,对于创建操作,比如购买某个商品,如果由于某种原因,手抖,控件bug,网络错误,可能导致一次操作实际上购买了多次同一个产品。所以,我们要考虑防止重复提交。这个重复提交我们只限定于创建操作,对于修改和删除操作,原则上是幂等的,不用担心,查询操作更不用担心重复操作。 方案一,前端在提交时候生成一个基于时间的sequence,将这个参数传到后端,后端根据uriPath+userId+sequence作为key,采用redis分布式锁,setNX,防止重复提交 方案二,前端不用传递sequence,后端根据请求的payload和其他参数来确定唯一,uriPath+userId+MD5(JsonString(所有参数))作为key,用redis分布式锁 具体实现: 对于方案一,防止重复提交交给了前端控制,sequence的生成可以是时间戳。后端可以做在servlet filter 中或者在restful 框架的filter中比如resteasy 的ContainerRequestFilter中 对于第二种方案,防止重复提交完全由后端控制,前端无感,不能做在filter中,因为request payload只能被消费一次。可以用spring aop来实现

java web 之 AJAX用法

蹲街弑〆低调 提交于 2020-12-12 08:24:49
AJAX :Asynchronous JavaScript And XML 指异步 JavaScript 及 XML一种日渐流行的Web编程方式 Better Faster User-Friendly 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS新用法。 呈上AJAX之父 Jesse James Garrett 大佬帅照, emmm 很有魔性的笑容~ AJAX交互模型 AJAX编码步骤 1、创建XmlHttpRequest对象 2、注册状态监控回调函数 3、建立与服务器的异步连接 4、发出异步请求 如下是一个搜索框提示的JavaScript函数写法 1 window.onload = function(){ 2 // 得到搜索框对象 3 var searchElement = document.getElementById( " name " ); 4 var div = document.getElementById( " context1 " ); 5 searchElement.onkeyup = function(){ 6 // 给文本框注册事件 7 var name = this .value; 8 if (name== "" ){ 9 div.style.display= "

JPA之@Transient

心不动则不痛 提交于 2020-12-12 05:15:05
java 的transient关键字的作用是需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。 使用示例: import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Transient; @Entity public class OrderEntity { @Id // ... private String id; /* * * 附件id不需要持久化 */ @Transient private String attachMgr; } transient 使用小结:   1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。   2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口   3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。  相关参考资料: transient关键字使用小记 来源: oschina 链接: https