package com.alanluo.recorder; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class test2 { public static void main(String[] args) { // TODO Auto-generated method stub List<String> list = new ArrayList<>(); list.add("D:/1/jasndfjhamsfnaoihjsdfasd.tmp0"); list.add("D:/1/jasndfjhamsfnaoihjsdfasd.tmp1"); String targetPath = "D:/1/marge.pcm"; FileInputStream in = null; FileOutputStream out = null; try { //新建一个目标文件对象 File target = new File(targetPath); //实例化一个文件流输出对象 out = new FileOutputStream(target); //循环读取要合并的文件集合 for(String path:list) { //文件对象 File file = new File(path); if (file.exists()) { System.out.println("filePath:"+file.getAbsolutePath()+" file:"+file.length()); byte[] buf = new byte[1024]; int len = 0; in = new FileInputStream(file); while ((len = in.read(buf)) != -1) { //写出数据 out.write(buf, 0, len); } if (in != null) { in.close(); } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if (out != null) { try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
tomcat配置SSL环境
生成安全证书:
1.java环境:因为SUN公司提供了制作证书的工具keytool。在JDK 1.4以后的版本中都包含了这一工具,它的位置为<JAVA_HOME>\bin\keytool.exe。
2.创建证书的命令:
- keytool -genkeypair -alias “tomcat” -keyalg “RSA” -keystore “f:\tomcat.keystore”
参数的意思如下:
这里密码我输的是tomcat,名字与姓氏为域名,其它的根据具体情况输入
以上命令将生产一对非对称密钥和自我签名的证书f:\tomcat.keystore.
将证书保存到你要存放的地方,我的保存在D:\Tools\Web\ssl\tomcat.keystore
注意:“名字与姓氏”应该是域名,输成了姓名,和真正运行的时候域名不符,会出问题
—————————————————————————————————————————
配置tomcat:
定位到tomcat的安装目录,找到conf下的server.xml文件
找到如下已经被注释的代码:
<!– <Connector port=”8443″ protocol=”org.apache.coyote.http11.Http11NioProtocol”
maxThreads=”150″ SSLEnabled=”true” scheme=”https” secure=”true” keystoreFile=”/root/shangdao.keystore” keystorePass=”111111″
clientAuth=”false” sslProtocol=”TLS” /> –>
去掉注释,修改为:
这里,密码和证书的位置根据个人的具体环境而设置,属性参数如下所述:
属性 | 描述 |
clientAuth | 如果设为true,表示Tomcat要求所有的SSL客户出示安全证书,对SSL客户进行身份验证 |
keystoreFile | 指定keystore文件的存放位置,可以指定绝对路径,也可以指定相对于<CATALINA_HOME>(Tomcat安装目录)环境变量 的相对路径。如果此项没有设定,默认情况下,Tomcat将从当前操作系统用户的用户目录下读取名为“.keystore”的文件。 |
keystorePass | 指定keystore的密码,如果此项没有设定,在默认情况下,Tomcat将使用“changeit”作为默认密码。 |
sslProtocol | 指定套接字(Socket)使用的加密/解密协议,默认值为TLS,用户不应该修改这个默认值。 |
ciphers | 指定套接字可用的用于加密的密码清单,多个密码间以逗号(,)分隔。如果此项没有设定,在默认情况下,套接字可以使用任意一个可用的密码。 |
访问支持ssl的web站点:
启动tomcat,在浏览器中输入:https://localhost:8443/。
Java使用websocket实现聊天室简单功能
最近有个项目需要实现视频流的信息交换处理,但是之前一直都没有写过有关的代码,所以就想到了websocket接口。
java创建一个socket非常简单,繁琐的可能是日常的业务信息处理,下面看下一段代码:
import model.User; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; /** * Created by alan.luo on 2017/9/10. */ @ServerEndpoint(value = "/websocket2") public class TestWebSocket { @OnOpen public void onOpen(Session session, EndpointConfig endpointConfig) { sendMsg(session,"Welcome back."); //push list. User user = new User(); user.setId(Integer.parseInt(session.getId())); Map<String,List<String>> map = session.getRequestParameterMap(); user.setUserName(map.get("userName").get(0)); user.setSession(session); //has client come in,so server must be save the session to the application.class. Application.getInstance().putSession(user); } @OnMessage public void onMessage(Session session,String message){ System.out.println("++++++++++:"+message); //if has user push message to the server.then server will each all the client and send message too. for (User user:Application.getInstance().getUsers()){ sendMsg(user.getSession(),user.getUserName() + " say:"+message); } } @OnClose public void onClose(Session session, CloseReason closeReason){ List<User> list = Application.getInstance().getUsers(); //pop list. for (int i = 0;i<list.size();i++){ if (Integer.parseInt(session.getId()) == list.get(i).getId()){ list.remove(i); Application.getInstance().setUsers(list); break; } } } @OnError public void onError(Session session, Throwable thr) { System.out.println("+++++++++onError"+thr.getMessage()); } /** * send message to session. * @param session * @param message */ protected void sendMsg(Session session,String message){ System.out.println(message); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { session.getBasicRemote().sendText(message+" >"+sdf.format(new Date())); } catch (IOException e) { e.printStackTrace(); } } }
当有客户端进入,则把客户端保存到application这个实例中,application是自定义的一个类,实现了单例,所以保存进去是最合适的,当有消息进入时,server将从application读取session list 并且遍历全部session and send the message。
Application实例的代码:
import model.User; import java.util.ArrayList; import java.util.List; /** * Created by alan.luo on 2017/9/10. */ public class Application { private List<User> users; private static Application app; public Application(){ users = new ArrayList<>(); } public static Application getInstance(){ if (app == null){ app = new Application(); } return app; } public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public void putSession(User s){ this.users.add(s); } }
User实体类的代码:
package model; import javax.websocket.Session; /** * Created by alan.luo on 2017/9/6. */ public class User { private int id; private String userName; private String userPassword; private Session session; public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPasswd) { this.userPassword = userPasswd; } @Override public String toString() { return "User{" + "id=" + id + ", userName='" + userName + '\'' + ", userPassword='" + userPassword + '\'' + '}'; } }
可能会有错误,那是因为需要配置一下web.xml
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/websocket2</url-pattern> </servlet-mapping>
剩下的就是javascript客户端的代码了:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <p><input type="text" id="userName" value="" placeholder="输入名字进入聊天室"></p> </div> <div> <textarea rows="16" cols="40" id="content"></textarea> </div> <div> <input type="text" id="message" value="" placeholder="输入内容"/> <button type="button" id="send">send</button> </div> <div> <button type="button" id="connect">connect</button> <button type="button" id="destroy">destroy</button> </div> <script> var connect = document.getElementById("connect"); var content = document.getElementById("content"); var message = document.getElementById("message"); var destroy = document.getElementById("destroy"); var send = document.getElementById("send"); var userName = document.getElementById("userName"); var socket = null; connect.addEventListener("click",function () { console.log("connect") if(userName.value.length <= 2){ return false; } socket = new WebSocket("ws://localhost:8080/websocket2?userName="+userName.value); socket.onopen = function (p1) { console.log("onopen",p1) } socket.onclose = function (p1) { console.log("onclose",p1) } socket.onerror = function (p1) { console.log("onerror",p1) } socket.onmessage = function (p1) { console.log("onmessage",p1) content.innerHTML = (content.innerHTML + p1.data + "\n") } }); destroy.addEventListener("click",function () { console.log("destroy") socket.close(); }); send.addEventListener("click",function () { console.log("send") socket.send(message.value); message.value = ""; }); </script> </body> </html>
最后上传一张效果图吧:
registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister
解决方法,新建类并且继承org.apache.commons.dbcp.BasicDataSource类
接着重新close的方法即可。
/** * registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister * Created by alan.luo on 2017/9/5. */ public class BasicDataSourceEx extends BasicDataSource { public BasicDataSourceEx(){ super(); } @Override public synchronized void close() throws SQLException { DriverManager.deregisterDriver(DriverManager.getDriver(url)); super.close(); } }
xml把bean对应的class改成新建的类名就可以了。
<bean id="dataSource" class="com.lanxinbase.system.basic.BasicDataSourceEx" destroy-method="close"> <property name="driverClassName" value="${db.driver}"/> <property name="url" value="${db.url}"></property> <property name="username" value="${db.username}"></property> <property name="password" value="${db.userpasswd}"></property> <property name="initialSize" value="${db.initalsize}"></property> <property name="maxActive" value="${db.maxActive}"></property> <property name="maxIdle" value="${db.maxIdle}"></property> <property name="maxOpenPreparedStatements" value="${db.maxOpens}"></property> <property name="maxWait" value="${db.maxWait}"></property> </bean>
解决spring mvc跨域的问题
java开发网站是很繁琐的事情,特别是写前端,每次运行都需要进行编译,所以需要配置跨域访问:
服务端
首先要创建一个CrossDomainFilter类,类继承了Servlet Filter接口,如下代码:
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by alan.luo on 2017/9/5. */ public class CrossDomainFilter extends Compact implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { try { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 跨域 String origin = httpRequest.getHeader("Origin"); if (origin == null) { httpResponse.addHeader("Access-Control-Allow-Origin", "http://localhost/"); } else { httpResponse.addHeader("Access-Control-Allow-Origin", origin); } httpResponse.addHeader("Access-Control-Allow-Headers", "Origin, x-requested-with, Content-Type, Accept,X-Cookie"); httpResponse.addHeader("Access-Control-Allow-Credentials", "true"); httpResponse.addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE"); if ( httpRequest.getMethod().equals("OPTIONS") ) { httpResponse.setStatus(HttpServletResponse.SC_OK); return; } filterChain.doFilter(request, response); } catch (Exception e) { e.printStackTrace(); throw e; } } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
类方法主要是配置response的响应信息,告诉客户端,可以传递什么及使用什么方法过来。
接下来就是配置xml文件,打开web.xml文件,在过滤代码中加入以下代码:
<!-- 允许跨域 --> <filter> <filter-name>CrossDomainFilter</filter-name> <filter-class>com.test.com.CrossDomainFilter</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CrossDomainFilter</filter-name> <url-pattern>/*</url-pattern><!-- 配置允许跨域访问的的url-pattern --> </filter-mapping>
到这里服务器就已经配置完毕了。
客户端
客户端直接使用ajax发起请求就可以:
/** * 发起ajax请求 * @param url 请求地址 * @param data 请求参数(object)对象 * @param fnScuss 成功回调的函数 * @param fnError 失败回调的函数 * @returns {{get: get, post: post}} */ ajax: function (url, data, fnScuss, fnError) { var _cacheKey = app.md5(url+JSON.stringify(data)); var _cache = null; var _isCanCache = app.isCanCache(url); url = this.constant.DOMAIN + url; var http = function (method,header) { if (method == null){ method = "POST"; } if(header == null){ header = new Object(); } $.ajax({ url: url, data: data, dataType: "json", type: method, headers: header, beforeSend: function(xhr) { xhr.withCredentials = true; }, crossDomain:true, success: function (e) { if (typeof fnScuss == "function") { //储存缓存 if (e.code == "1" && _isCanCache == true){ //app.cache.set(_cacheKey,e) } fnScuss(e); } }, error: function (e) { if (typeof fnError == "function") { fnError(e); } } }) }; return { get: function () { //缓存判断 if (_isCanCache == true){ _cache = app.cache.get(_cacheKey) if (_cache != null && typeof fnScuss == "function"){ fnScuss(_cache); return true; } } http("GET"); }, post: function (isJson) { //缓存判断 if (_isCanCache == true){ _cache = app.cache.get(_cacheKey) if (_cache != null && typeof fnScuss == "function"){ fnScuss(_cache); return true; } } var header = new Object(); if (isJson == true){ header['Content-Type'] = "application/json"; } http("POST",header); }, delete:function () { http("DELETE"); }, put:function () { http("PUT"); } } },
app.event("#getToken", "click", function () { app.ajax("/project/api/getToken", {type:"1"}, function (e) { app.log(e); if (e.code == 1) { } }).post(); });
近期评论