调用外部程序或脚本

 在编写Java程序时,有时候我们需要调用其他的诸如exe,shell这样的程序或脚本。在Java中提供了两种方法来启动其他程序:

 (1) 使用Runtime的exec()方法 

(2) 使用ProcessBuilder的start()方法 。

Runtime和ProcessBulider提供了不同的方式来启动程序,设置启动参数、环境变量和工作目录。但是这两种方法都会返回一个用于管理操作系统进程的Process对象。
JDK帮助文档上这么说:如有必要,一直要等到由该 Process 对象表示的进程已经终止。
如果已终止该子进程,此方法立即返回。但是直接调用这个方法会导致当前线程阻塞,直到退出子进程。
对此JDK文档上还有如此解释:因为本地的系统对标准输入和输出所提供的缓冲池有效,
所以错误的对标准输出快速的写入何从标准输入快速的读入都有可能造成子进程的所,甚至死锁。

  Process类是一个抽象类,其内部所有的方法都是抽象的,Runtime.exec()方法可以创建一个本地进程,并返回Process子类的一个实例。
Process类的API如下:
l  destroy():杀掉子进程
l  exitValue():返回子进程的出口值
l  InputStream getErrorStream():获得子进程的错误流
l  InputStream getInputStream():获得子进程的输入流
l  OutputStream getOutputStream():获得子进程的输出流
l  waitFor():导致当前进程等待,一直等到由该Process对象表示的进程已经终止      

Process.exitValue() 采用非阻塞的方式返回,如果没有立即拿到返回值,则抛出异常
Process.waitFor() 当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。但是如果我们在调用此方法时,如果不注意的话,很容易出现主线程阻塞,Process也挂起的情况。在调用waitFor() 的时候,Process需要向主线程汇报运行状况,所以要注意清空缓存区,即InputStream和ErrorStream。


系统变量与环境变量

System.getenv   System.getProperty()(System.getProperties)
* <table summary="Shows property keys and associated values">
     * <tr><th>Key</th>
     *     <th>Description of Associated Value</th></tr>
     * <tr><td><code>java.version</code></td>
     *     <td>Java Runtime Environment version</td></tr>
     * <tr><td><code>java.vendor</code></td>
     *     <td>Java Runtime Environment vendor</td></tr
     * <tr><td><code>java.vendor.url</code></td>
     *     <td>Java vendor URL</td></tr>
     * <tr><td><code>java.home</code></td>
     *     <td>Java installation directory</td></tr>
     * <tr><td><code>java.vm.specification.version</code></td>
     *     <td>Java Virtual Machine specification version</td></tr>
     * <tr><td><code>java.vm.specification.vendor</code></td>
     *     <td>Java Virtual Machine specification vendor</td></tr>
     * <tr><td><code>java.vm.specification.name</code></td>
     *     <td>Java Virtual Machine specification name</td></tr>
     * <tr><td><code>java.vm.version</code></td>
     *     <td>Java Virtual Machine implementation version</td></tr>
     * <tr><td><code>java.vm.vendor</code></td>
     *     <td>Java Virtual Machine implementation vendor</td></tr>
     * <tr><td><code>java.vm.name</code></td>
     *     <td>Java Virtual Machine implementation name</td></tr>
     * <tr><td><code>java.specification.version</code></td>
     *     <td>Java Runtime Environment specification  version</td></tr>
     * <tr><td><code>java.specification.vendor</code></td>
     *     <td>Java Runtime Environment specification  vendor</td></tr>
     * <tr><td><code>java.specification.name</code></td>
     *     <td>Java Runtime Environment specification  name</td></tr>
     * <tr><td><code>java.class.version</code></td>
     *     <td>Java class format version number</td></tr>
     * <tr><td><code>java.class.path</code></td>
     *     <td>Java class path</td></tr>
     * <tr><td><code>java.library.path</code></td>
     *     <td>List of paths to search when loading libraries</td></tr>
     * <tr><td><code>java.io.tmpdir</code></td>
     *     <td>Default temp file path</td></tr>
     * <tr><td><code>java.compiler</code></td>
     *     <td>Name of JIT compiler to use</td></tr>
     * <tr><td><code>java.ext.dirs</code></td>
     *     <td>Path of extension directory or directories</td></tr>
     * <tr><td><code>os.name</code></td>
     *     <td>Operating system name</td></tr>
     * <tr><td><code>os.arch</code></td>
     *     <td>Operating system architecture</td></tr>
     * <tr><td><code>os.version</code></td>
     *     <td>Operating system version</td></tr>
     * <tr><td><code>file.separator</code></td>
     *     <td>File separator ("/" on UNIX)</td></tr>
     * <tr><td><code>path.separator</code></td>
     *     <td>Path separator (":" on UNIX)</td></tr>
     * <tr><td><code>line.separator</code></td>
     *     <td>Line separator ("\n" on UNIX)</td></tr>
     * <tr><td><code>user.name</code></td>
     *     <td>User's account name</td></tr>
     * <tr><td><code>user.home</code></td>
     *     <td>User's home directory</td></tr>
     * <tr><td><code>user.dir</code></td>
     *     <td>User's current working directory</td></tr>
     * </table>
Basic
replaceAll
replaceFirst
replaceFirst("\\$\\{CRITERIA\\}", innerCriteriaStr)
${CRITERIA} 替换这个


这两个用的是正则。replaceall 第一个参数是正则表达式
而replace 就可以直接替换

java foreach 的用法
  for (int x : arr) {
             System.out.println(x); //逐个输出数组元素的值
         }



这种用法看上去是地址传递       

private JSONObject getColHeaderOfGate(JSONObject colHeaderObj,MTIObject mileStonObj,int recurLevel)
        {
                JSONObject colJSObj = colHeaderObj;

GBK 编码 
一个中文字符占用两个字节
UTF-8 编码
一个中文字符占用三个字节


通过字节获取字符:
    byte[] byte2 =new byte[]{-48,-62};
    snew = new String(byte2, "GBK");


通过字符获取字节
    String s = "新测试场景.txt";
    byte[] byte1 = s.getBytes();


4. HashSet
里面不能有重复的元素


命令行执行

linux 下一定要用冒号分隔


编译(Test.java的package不要写):


javac -classpath dom4j.jar Test.java --引入需要的包


执行


java -classpath .:dom4j.jar Test --引入包, . 是Test.class在当前文件夹; : 是分隔符


javac 编译成.class 文件后,使用java执行, 需切换到basic的上一层目录
java basic.FileTest

方法注释

 /**
         * search All Group contain a keyWord from SOA AD Web Service
         * @param keyWord
         * match in group name, if null, get all group 
         * @return list
         * Group name list, as ""
         * @throws SOAADGroupServiceException
         * if proxy socket timeout, new proxy one time again , if fail , throw exception;
         * if returnCode not "S", throw exception 
         */


方法的注释必须放在所描述的方法之前,方法注释中常用的标记有如下:


@param  描述方法参数,描述时需指定参数名称格式为


                  @param variable description


多个参数可以指定多行如下


/**


     @param temp 温度


     @param humidity 湿度


     @param pressure  气压


     */


    public void update (float temp, float humidity, float pressure);


}
@return  描述方法返回类型
@throws 描述方法抛出的 异常


/**  
* The doGet method of the servlet.  
* This method is called when a form has its tag value method  
   * equals to get.  
* @param request  
*  the request send by the client to the server  
* @param response  
*  the response send by the server to the client  
* @throws ServletException  
*  if an error occurred  
* @throws IOException  
*  if an error occurred  
*/

JRE for browser

Firefox和Chrome需要使用单独的插件才能使用JRE


IE和Firefox可以在控制台设置


Chrome却更特殊, 可以按以下方式配置或重新安装JRE


pparently, Chrome addresses a key in Windows registry when it looks for a Java Environment. Since the plugin installs the JRE, this key is set to a JRE path and therefore needs to be edited if you want Chrome to work with the JDK. 


    Run the plugin installer anyways; 


    Start -> Run (Winkey+R) and then type in regedit command to access the registry; 


    Locate HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MozillaPlugins\@java.com/JavaPlugin and export it as a reg file to say, your desktop (right click and select Export); 


    Uninstall the JRE (Control Panel -> Add or Remove Programs). This should delete the key above, explaining the need to export it in the first place; 


    Open the reg file exported to your desktop with a text editor like notepad++. Locate this snippet and edit "Path" so that it matches the corresponding dll inside your JDK installation; 


    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MozillaPlugins\@java.com/JavaPlugin] 

    "Description"="Oracle® Next Generation Java™ Plug-In" 

    "GeckoVersion"="1.9" 


    "Path"="C:\Program Files (x86)\Java\jdk1.6.0_29\jre\bin\new_plugin\npjp2.dll" 


    "ProductName"="Oracle® Java™ Plug-In" 

    "Vendor"="Oracle Corp." 

    "Version"="160_29" 


    Save file; 


    Double click modified reg file to add keys to your registry.




3.firefox jre 插件


npjp2.dll


转义字符



\ 是转义字符。 \ 后面可以加8进制或是16进制的数值
\63 得到的值是  3。

如果一个字符串中出现\63这样的子串,直接使用replace 是无法替换的。
需要单个比较字符替换

但是, 如果从xml直接读取的, 还在方法中的不会转换**


安全

 J2EE 安全框架由三个 API 组成:Java 认证和授权服务(JAAS:http://java.sun.com/products/archive/jaas/
;http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html
security.pdf
)、Java 安全套接字扩展(JSSE)和 Java 加密扩展(Java Cryptography Extension,JCE)。
   JAAS 提供了一种灵活的、说明性的机制,用于对用户进行认证并验证他们访问安全资源的能力。JSSE 定义了通过安全套接字层(SSL)进行安全 Web 通信的一种全 Java 的机制。通过结合这两种技术,可以使我们的应用程序:
  验证用户就是他或者她所宣称的那个人(认证)。
  保证允许他或者她访问所要求的资源(授权)。
  通过安全网络连接进行完整的信息交换(传输)。
  JAAS定义了可插拔的认证机制,使认证逻辑独立开来,可通过修改配置文件切换认证模块。
JAAS API 定义了应用程序代码与将要执行业务逻辑的物理实现之间干净的抽象。这个抽象层不用重新编译现有的应用程序代码就可以作为登录模块的运行时替代。特别是,应用程序写到 LoginContext API,而认证技术提供程序则写到 LoginModule 接口。在运行时, LoginContext 将读取配置文件以确定应使用哪一个(一些)登录模块对访问特定应用程序的用户进行认证。
   JAAS 所使用的认证方案以两种非常重要的实体为基础:principal 和 subject。实际被认证的人或者服务称为 subject。 principal是一个惟一的实体,比如个人或者组的名字、帐号、社会安全号或者类似的惟一标识。为了惟一标识一个 subject(这是认证的关键部分),一个或者多个 principal 必须与这个 subject 相关联。
   认证和授权信息以明文形式――即 HTTP、TCP/IP、FTP等――传递安全信息(包括认证信息)。如果需要保证数据在传输时不会被未授权的人访问;而且需要保证数据在到达之前,没有在传输过程中修改过。要达到这个目的,可以利用安全套接字层(SSL)和传输层安全性(Transport Layer Security,TLS)协议实现这两种功能 




hibernate方言

RDBMS         方言
DB2         org.hibernate.dialect.DB2Dialect
DB2 AS/400         org.hibernate.dialect.DB2400Dialect
DB2 OS390         org.hibernate.dialect.DB2390Dialect
PostgreSQL         org.hibernate.dialect.PostgreSQLDialect
MySQL         org.hibernate.dialect.MySQLDialect
MySQL with InnoDB         org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM         org.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version)         org.hibernate.dialect.OracleDialect
Oracle 9i/10g         org.hibernate.dialect.Oracle9Dialect
Sybase         org.hibernate.dialect.SybaseDialect
Sybase Anywhere         org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server         org.hibernate.dialect.SQLServerDialect
SAP DB         org.hibernate.dialect.SAPDBDialect
Informix         org.hibernate.dialect.InformixDialect
HypersonicSQL         org.hibernate.dialect.HSQLDialect
Ingres         org.hibernate.dialect.IngresDialect
Progress         org.hibernate.dialect.ProgressDialect
Mckoi SQL         org.hibernate.dialect.MckoiDialect
Interbase         org.hibernate.dialect.InterbaseDialect
Pointbase         org.hibernate.dialect.PointbaseDialect
FrontBase         org.hibernate.dialect.FrontbaseDialect
Firebird         org.hibernate.dialect.FirebirdDialect



JSP 九大内置对象



blog.csdn.net/lenhan12345/article/details/1566594


Ip, 机器名和用户


String ipAddress = request.getHeader("X-FORWARDED-FOR");  
if (ipAddress == null) {  
       ipAddress = request.getRemoteAddr();  
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { 
    Logger.getLogger(this.getClass()).warning("Inside Confirm Servlet");  
    response.setContentType("text/html");
    String hostname = request.getRemoteHost(); // hostname
    System.out.println("hostname"+hostname);
    String computerName = null;
    String remoteAddress = request.getRemoteAddr();
    System.out.println("remoteAddress: " + remoteAddress);
    try {
        InetAddress inetAddress = InetAddress.getByName(remoteAddress);
        System.out.println("inetAddress: " + inetAddress);
        computerName = inetAddress.getHostName();
        System.out.println("computerName: " + computerName);
        if (computerName.equalsIgnoreCase("localhost")) {
            computerName = java.net.InetAddress.getLocalHost().getCanonicalHostName();
        } 
    } catch (UnknownHostException e) {


        }
    System.out.println("computerName: " + computerName);
}



request.getRemoteUser
Returns the login of the user making this request, if the user has been authenticated, or null if the user has not been authenticated. Whether the user name is sent with each subsequent request depends on the browser and type of authentication. Same as the value of the CGI variable REMOTE_USER.

request.getRemoteUser does not return the loginname the user used to log in to their computer. It returns the username used to log into the web application (although it is sometimes possible to use NTLM to automaticly log into a web application).





SSO参考

可以和ldap集成

可以用证书
http://www.javaeye.com/wiki/SSO/ ... 9%E8%AF%81%E4%B9%A6
用windows帐户sso
sap好像用这个玩意
Kerberos


Basic认证

In case of HTTP BASIC authentication, the username is available by HttpServletRequest#getRemoteUser().
So, in Servlet:
String username = request.getRemoteUser();
// ...

and in JSP:
<p>Welcome, ${pageContext.request.remoteUser}</p>
Further, the user principal is available by HttpServletRequest#getUserPrincipal().
share|improve this answe



最近的项目需要Apache2+tomcat6配置Basic认证,项目后台需要得到Basic认证的用户名,但是始终request.getRemoteUser()=null。这几天通过查看 mod_jk文档 和在同事的帮助下,终于使得index.jsp页面上<%= request.getRemoteUser() %>不再为null。


主要过程


下面我把使用的主要配置说明一下.首先,在${TOMCAT_HOME}/conf /server.xml里面,找到AJP13对应的那个 connector节点,添加tomcatAuthentication="false" ,这个属性默认是True,意思是使用Tomcat本身的认证,不使用外部Server传进来的认证信息。 然后,在apache的httpd.conf配置文件中,使用的JkMount和JkUnMount这两个指令是由mod_jk提供的,JkMount指令把请求转给tomcat,与之相反的是JkUnMount不转发请求。下面是我的配置:



JkEnvVar REMOTE_USER null


JkMount /*.jsp  ajp13_worker


JkMount /Test/*  ajp13_worker


JkUnMount /Test/ ajp13_worker




JkEnvVar指令可以使从Apache转发环境变量给Tomcat。这些变量可以从Servlet中的request.getAttribute(attributeName)得到,但是通过JkEnvVar发送的变量名称不会出现在request.getAttributeNames()中。 




要是使request.getRemoteUser()不返回null,整个站点的验证模式至少设为基本验证,不能设为匿名登录。由于我们通常是由应用自己来进行访问控制,所以站点的设定都是匿名登录。有的应用服务器支持验证时使用LDAP或是数据库。有的可以使用系统帐号。



我的意见:使用应用服务器提供的验证机制将使部署依赖与特定的应用服务器,所以没有所谓多应用统一身份认证和单点登录需求的话,我宁愿选择将访问控制写在应用里。



你理解的没有错,使用Basic等验证方法登陆之后,就会返回用户名。 



网页缓存

response.setHeader("Cache-Control","private")

网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。其作用根据不同的重新浏览方式分为以下几种情况。
打开新窗口
如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器
在地址栏回车
如果值为private或must-revalidate(和网上说的不一样),则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。
按后退按扭
如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问






include



 使用jsp:include 方式导入数据时,
导入文件名要为 jsp 后缀。
这种导入方式是分别编译,如果不是.jsp 后缀的, 就不会编译


JSP编码



http://my.oschina.net/hcom/blog/4436jsp 中的pageEncoding和contentType两种属性的区别:
pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码


JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。


第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。


第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。


JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。


第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效