查看JBoss控制台JMX-Console
//可以通过这个页面进行对 JBOSS 的各服务的配置和管理。
http://localhost:8080/jmx-console/
查看发布的WebService(进入 JbossWS 的查看界面)
http://localhost:8080/jbossws/
1.WAR文件的部署
JBoss支持热部署,也就是war文件部署到服务器上后不需要重新启动JBoss(Tomcat不支这种特性)。war文件的部署很简单,直接将war文件拷贝到JBoss/server/default/deploy目录下即可。
2.JBoss的目录结构
bin:包含各种脚本文件以及相关文件,比如run.bat和shutdown.bat批处理文件。
client:存储配置信息和可能被Java客户端应用程序或外部Web容器用到的jar文件。
docs:保存在JBoss中引用到的XML文件和DTD文件(这里也提供了在JBoss中如何写配置文件的例子)。该目录下有针对不同的数据库(如MySql、Oracle、SQL Server、Postgres等)配置数据源的JCA配置文件。
lib:一些 JAR,JBoss 启动时加载,且被所有 JBoss 配置共享。(不要把你的库放在这里)
server: 这里的每一个子目录对应着一个服务器配置。该配置由运行脚本文件时的参数"-c <配置名称>"来确定。在server目录下有三个配置例子,即all、default和minimal,每一个配置安装的服务都不一样。 其中default下是缺省配置。
minimal:仅加载启动JBoss所需的最少服务,如日志服务、JNDI和URL部署扫描器(发现新的部署),不包含Web容器、EJB和JMS。
all:启动所有的服务,包括RMI/IIOP、集群服务和Web服务部署器(默认配置不会被加载)。
启动JBoss时,如果run.bat不带任何参数,则使用的配置是server/default目录下的配置。如果要以其它目录下的配置启动JBoss,可以使用如下参数:
run -c all
上述命令将以all目录下的配置信息启动JBoss。也可以在server目录下新建目录,按自己的需要写配置文件。
下面以default目录为例,介绍服务器配置的目录结构。
conf:该目录下有指定核心服务的jboss-service.xml文件,也可以放其它服务配置的文件。
data:该目录是JBoss内置的数据库Hypersonic存储数据的地方,也是JBossMQ(the JBoss implementation of JMS)存储相关信息的地方。
deploy: 这是部署J2EE应用程序(jar、war和ear文件)的位置,只需将相应文件拷贝到该目录下即可。该目录也用来热部署服务和JCA资源适配器。已经有 一些服务部署到这个目录了,如jmx-console,你启动JBoss后即可访问。JBoss会周期性的扫描deploy目录,当有任何组件改 变,JBoss会重新部署该程序。
lib:存放服务器配置所需的jar文件,比如,你可以将JDBC驱动程序放在该目录下。
log:存放日志信息。JBoss使用Jakarta log4j包存储日志,在程序中你也可以直接使用该信息。
tmp:存储在部署过程中解压时产生的临时文件。
work:Tomcat编译JSP文件时的工作目录。
目录data、log、tmp和work在JBoss安装后并不存在,当JBoss运行时自动建立。
另外,连接数据库所用到的JDBC驱动程序要拷贝到JBoss_HOME /server /default /lib 目录下。
3. JBoss中的部署
JBoss中的部署过程非常的简单、直接并且支持热部署。在每一个配置中,JBoss不断的扫描一个特殊的目录的变化:$JBOSS_HOME/server/config-name/deploy。
你可以把下列文件拷贝到此目录下:
* 任何jar库(其中的类将被自动添加到JBoss的classpath中)
* EJB JAR
* WAR (Web Appliction aRrchive) 注意默认情况下context为war名称.
* EAR (Enterprise Application aRchive)
* 包含JBoss MBean定义的XML文件
* 一个包含EJB JAR、WAR或者EAR的解压缩内容,并以.jar、.war或者.ear结尾的目录
二、实体 Bean发布前的准备工作
1、配置数据源XML并放置在[jboss安装目录]/server/default/deploy目录,
把数据库驱动Jar包放置在[Jboss安装目录]\server\default\lib 目录下,
放置后需要重启Jboss服务器。如果数据源已经存在就不需要配置。
2、配置 persistence.xml文件,在文件中指定使用的源据源及各项参数。
3、把实体类和 persistence.xml文件打成 Jar,persistence.xml放在 jar文件的 META-INF目录
各种数据库的数据源配置模版你可以在[Jboss安装目录]\docs\examples\jca目录中找到,默认名称为:数据库名+ -ds.xml 。
三、日志文件设置
若需要修改JBoss默认的log4j设置,可修改JBoss安装目录"server\default\conf下的jboss-log4j.xml文件,在该文件中可以看到,log4j的日志输出在JBoss安装目录server\default\log下的server.log文件中。
不同应用生成到不同日志文件:
<!-- 应用日志输出 --> <appender name="LIGHTESB" class="org.jboss.logging.appender.DailyRollingFileAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="File" value="${jboss.server.log.dir}/lightesb.log"/> <!-- 就改了生成文件名称 --> <param name="Append" value="true"/> <param name="DatePattern" value="'.'yyyy-MM-dd"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/> </layout> </appender> <appender name="WS" class="org.jboss.logging.appender.DailyRollingFileAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="File" value="${jboss.server.log.dir}/webservice.log"/> <param name="Append" value="true"/> <param name="DatePattern" value="'.'yyyy-MM-dd"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/> </layout> </appender> <!-- 应用日志输出 --> <category name="com.soa.lightesb"> <priority value="DEBUG"/> <appender-ref ref="LIGHTESB"/> </category> <!--服务日志输出 --> <category name="com.soa.ws"> <priority value="DEBUG"/> <appender-ref ref="WS"/> </category>
修改jboss日志级别:
由于JBOSS日志文件占用的空间太大,需要修改日志文件记录信息的级别
JBOSS服务中的记录日志文件:jboss-log4j.xml,修改<param name="Threshold" value="ERROR"/>
具体的value值有:DEBUG,INFO,WARN,ERROR.
JBOSS启动时加载顺序:
总结:
$JBOSS_HOME/common/lib =》 deployer目录下应用或者服务(包括配置的全局过滤器) =》 deploy下的数据源、队列和应用等
JBOSS每次发布的时候都会生成一些临时文件到\server\default\tmp\deploy下面去
JBOSS的机制就是,发布的时候将\server\default\deploy下面的一些基础的应用一起发布,而这些基础应用发布在temp的临时目录下,是作为所有应用的基础包,也就是说这些包的优先级要高于每个普通应用的包的。
需要注意的是:JBOSS在加载自带的核心JAR之后,将会优先加载下面的两个目录
1、D:\jboss\server\default\lib
2、D:\jboss\server\default\tmp\deploy
其中1会在2之前加载,而目录2是发布某个WAR,EAR,EJB等应用之后生成的临时的jar,这些应用的所有JAR会生成诸如temp*.jar的形式。本文开头提到的错误也就是在目录1中存在一个spring.jar的包,优先于各个应用的spring.jar包。
Jboss 5启动后只能从本机访问,不能从远程访问的解决办法
用netstat –na 查看,发现绑定到127.0.0.1上:
tcp 0 0 127.0.0.1:8080
D:\jboss-5.1.0.GA\server\default\deploy\jbossweb.sar\server.xml中的:
<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" connectionTimeout="20000" redirectPort="8443" />
将${jboss.bind.address}修改为0.0.0.0即可
JBOSS配置数据源后的访问
package com.test; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class JDBCUtil { private final static Logger logger = Logger.getLogger(JDBCUtil.class.getName()); // 数据源 private static DataSource ds; private static String dsName = "java:/datasources/visesbdb"; static { try { Context ctx = new InitialContext(); ds = (DataSource)ctx.lookup(dsName); } catch (NamingException e) { logger.warning("Can not lookup the data source which named : " + dsName); e.printStackTrace(); } } /** * 获取数据库连接 * * @return 数据库连接/null */ public static Connection getConnection(){ Connection conn = null; if(ds != null){ try { conn = ds.getConnection(); } catch (SQLException e) { logger.warning("Get Connection failed ..."); e.printStackTrace(); } } return conn; } /** * 关闭数据库连接 * * @param conn */ public static void closeConnection(Connection conn){ if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * * 通过查询sql获取结果集中第一行,第一列的值 * * @param 查询sql * @return */ public static Object QueryUniqueResult(String query){ Object result = null; Connection conn = getConnection(); if(conn != null){ try { PreparedStatement ps = conn.prepareStatement(query); ResultSet rs = ps.executeQuery(); if(rs.next()){ result = rs.getObject(1); } } catch (SQLException e) { logger.warning("execute query has error ..."); e.printStackTrace(); } } closeConnection(conn); return result; } }
package com.test; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class TestContextListener implements ServletContextListener{ public void contextInitialized(ServletContextEvent sce) { int access = 1; try { access = Integer.parseInt(JDBCUtil.QueryUniqueResult("SELECT T.CONFIG_VALUE FROM SYS_CONFIG T WHERE T.CONFIG_NAME = 'SRV_PARAMETER_CHECK_ACCESS'").toString()); } catch (Exception e) { } System.out.println(access); } public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub } }
配置好数据源XML后可直接访问。
jboss会自动查找server/default/deploy目录下 **-ds.xml文件.并读取其中内容.来得到相应DataSource
上例数据库XML放在:server\default\deploy\datasources\visesbdb-ds.xml:
内部JNDI名字为:
<datasources>
<local-tx-datasource>
<jndi-name>datasources/visesbdb</jndi-name>
...
过滤器
WEB工程的FIiter需配到自己的web.xml中
JAVA工程无法定义Filter
EJB工程可以定义Filter,可以作为JBOSS的全局过滤器使用。
全局过滤器配置在server\default\deployers\jbossweb.deployer\web.xml中:
<filter> <filter-name>mainFilter</filter-name> <filter-class>com.project.filter.MainFilter</filter-class> </filter> <filter-mapping> <filter-name>mainFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
/** * 该过滤器是一个全局的过滤器,过滤所有经过访问J2EE服务器的请求 */ public class MainFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(MainFilter.class); private ControlService cs = new ControlServiceImpl(); @Override public void destroy() { InstanceInfo.filterIsUp = false; } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { // 提取请求相关信息 String requestURI = ((HttpServletRequest)req).getRequestURI(); String ip = ServletUtils.getRequestIP((HttpServletRequest)req); // 当前时间[yyyy-MM-dd hh:mm:ss.SSS] 请求IP[IP] 请求地址[requestURI] logger.debug("[" + ip + "][" + requestURI + "]"); // 只对SOAP请求做这些特殊操作 // 判断是否是SOAP请求 // 判断是否是Rest请求 if(ServletUtils.isSoapRequest((HttpServletRequest)req) || ProxyServiceUtils.isRestRequest(((HttpServletRequest)req).getRequestURI())){ // 记录所有访问的服务 logger.info("[" + ip + "][" + requestURI + "]"); // 获取服务英文名称 String serviceNameEn = ProxyServiceUtils.getServiceNameByRequestUri(requestURI); // 服务鉴权 if(cs.accessAuth(serviceNameEn, ip)){ // 生成实例ID String uuid = InstanceInfo.getInstanceUUID(); // 日志开关 1 为开启,0为关闭 if("1".equals(Config.getConfigByName("log.switch"))){ logger.debug("log switch is on..."); // 封装请求对象 RequestData rd = InstanceInfo.getRequestData(); rd.setInstanceUUID(uuid); // 设置当前调用时间 rd.setDate(new Date(System.currentTimeMillis())); rd.setServiceNameEn(serviceNameEn); rd.setRequestURI(requestURI); rd.setIp(ip); // 设置测试标志 String testFlag = ((HttpServletRequest)req).getHeader("@test_flag"); if(testFlag != null && com.project.ws.constants.Constants.HTTPREQUEST_FOR_TEST_SERVICE.equals(testFlag.trim())){ rd.setIsTest(com.project.soa.ws.constants.Constants.HTTPREQUEST_FOR_TEST_SERVICE); } // 输入输出做封装处理用来获取输入输出 HttpServletRequestWrapper reqw = new HttpServletRequestWrapper((HttpServletRequest)req); HttpServletResponseWrapper resw = new HttpServletResponseWrapper((HttpServletResponse)res); chain.doFilter(reqw, resw); }else{ chain.doFilter(req, res); } InstanceInfo.removeInstanceUUID(); }else{ res.setContentType("text/xml;charset=UTF-8"); res.getWriter().write(SoapUtils.getAuthSoapMsg()); } }else{ chain.doFilter(req, res); } } @Override public void init(FilterConfig config) throws ServletException { InstanceInfo.filterIsUp = true; } }
..