- 浏览: 38298 次
- 性别:
- 来自: 北京
最新评论
-
on-the-way:
很精辟啊
最近仔细研究了一下Java的NIO以及线程并发,搞清了点思路,特作笔记如下(NIO篇) -
wdlfellow:
现在需要在项目中做单元测试了,学习mock中。。。
junit 中的mock 使用摘记
收藏列表
标题 | 标签 | 来源 | |
EXTJS4 郁闷的Loading | EXTJS4 郁闷的Loading | ||
store.on('load', function (store, records, successful, options) { if (successful && Ext.typeOf(combo.getPicker().loadMask) !== "boolean") { combo.getPicker().loadMask.hide(); } }); |
|||
handler: function (grid, rowIndex, colIndex, node, e, record, rowEl) { | extjs4 怎么取到所有columns的header 表头名 | ||
var column=Ext.getCmp('mygrid').getStore().fields; alert(column); |
|||
获取节点下的所有子节点 | 获取节点下所有子节点 | ||
public void getAllDeptListByParentId(Integer parentid,List<Dept> list){ List<Dept> childList=getDeptListByParentId(parentid); if(childList.size()==0)return; for(Dept dept:childList){ if(dept.getLeaf()==0){ list.add(dept)); getAllDeptListByParentId(dept.getId(),list); }else{ list.add(dept); } } } |
|||
httpclient | httpclient | ||
public String getResponseBody(String url){ HttpClient client = new HttpClient(); GetMethod method = new GetMethod(url); //这里加或者不加都可以,看情况定 method.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8"); method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000); method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); try { int statusCode = client.executeMethod(method); if(statusCode != HttpStatus.SC_OK){ System.err.println("Method failed: " + method.getStatusLine()); } byte[] responseBody = method.getResponseBody(); String str = new String(responseBody); //或者用以下方式获取结果(2) //String str2 = method.getResponseBodyAsString(); //或者用以下方式获取结果(3) //InputStream is = getMethod.getResponseBodyAsStream(); //String returnStr = convertStreamToString(is); return str; }catch(HttpException e){ System.err.println("Fatal protocol violation: " + e.getMessage()); e.printStackTrace(); }catch(IOException e){ System.err.println("Fatal transport error: " + e.getMessage()); e.printStackTrace(); }finally{ method.releaseConnection(); } return null; } |
|||
java nio socket 代码 | Java NIO socket编程实例 | ||
晚上学习了下Java 的 NIO Socket编程,写了下面这个小程序,包括服务器端与客户端。实现的功能为客户端向服务器端发送随即数目的消息,服务器端一条一条的回应。消息内容保存在talks.properties文件中,内容为: Hi=Hi Bye=Bye 床前明月光=疑是地上霜 举头望明月=低头思故乡 少小离家老大回=乡音无改鬓毛衰 天王盖地虎=宝塔镇河妖 我是甲=我是乙 我是客户端=我是服务器 我是周星驰=我是周润发 客户端会随即发送“=”左边的消息,服务器端会回应客户端“=”右边的消息。如果客户端想断开连接,会向服务器发送一个"Bye",然后服务器会回应一个"Bye“。收到服务器端的"Bye"后,客户端会断开连接。 当然,java的properties文件不接受中文内容,你需要native2ascii一下。talks.properties 的实际文件内容为: Hi=Hi Bye=Bye \u5E8A\u524D\u660E\u6708\u5149=\u7591\u662F\u5730\u4E0A\u971C \u4E3E\u5934\u671B\u660E\u6708=\u4F4E\u5934\u601D\u6545\u4E61 \u5C11\u5C0F\u79BB\u5BB6\u8001\u5927\u56DE=\u4E61\u97F3\u65E0\u6539\u9B13\u6BDB\u8870 \u5929\u738B\u76D6\u5730\u864E=\u5B9D\u5854\u9547\u6CB3\u5996 \u6211\u662F\u7532=\u6211\u662F\u4E59 \u6211\u662F\u5BA2\u6237\u7AEF=\u6211\u662F\u670D\u52A1\u5668 \u6211\u662F\u5468\u661F\u9A70=\u6211\u662F\u5468\u6DA6\u53D1 看下服务器端的代码。此例中的服务器端只有一个主线程,用于selector操作,并处理多个客户端的消息。在常规的socket编程中,每个客户端都需要单独开一个线程,效率比较低。代码为: package helloweenpad; import java.io.FileInputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.Iterator; import java.util.Properties; public class MyFirstNIOServer { public static final int PORT = 12315; protected Selector selector; protected Charset charset = Charset.forName("UTF-8"); protected CharsetEncoder charsetEncoder = charset.newEncoder(); protected CharsetDecoder charsetDecoder = charset.newDecoder(); protected Properties talks = new Properties(); int clientCount; public MyFirstNIOServer() throws Exception { talks.load(new FileInputStream("E:\\talk.properties")); selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(PORT)); // port serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// register p("Server localhost:" + PORT + " started. waiting for clients. "); while (true) { // selector 线程。select() 会阻塞,直到有客户端连接,或者有消息读入 selector.select(); Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); // 删除此消息 // 并在当前线程内处理。(为了高效,一般会在另一个线程中处理此消息,例如使用线程池等) handleSelectionKey(selectionKey); } } } public void handleSelectionKey(SelectionKey selectionKey) throws Exception { if (selectionKey.isAcceptable()) { // 有客户端进来 clientCount++; ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); Socket socket = socketChannel.socket(); // 立即注册一个 OP_READ 的SelectionKey, 接收客户端的消息 SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ); key.attach("第 " + clientCount + " 个客户端 [" + socket.getRemoteSocketAddress() + "]: "); p(key.attachment() + "\t[connected] ========================================="); } else if (selectionKey.isReadable()) { // 有消息进来 ByteBuffer byteBuffer = ByteBuffer.allocate(100); SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); try { int len = socketChannel.read(byteBuffer); // 如果len>0,表示有输入。如果len==0, 表示输入结束。需要关闭 socketChannel if (len > 0) { byteBuffer.flip(); String msg = charsetDecoder.decode(byteBuffer).toString(); // 根据客户端的消息,查找到对应的输出 String newMsg = talks.getProperty(msg); if (newMsg == null) newMsg = "Sorry? I don't understand your message. "; // UTF-8 格式输出到客户端,并输出一个'n' socketChannel.write(charsetEncoder.encode(CharBuffer.wrap(newMsg + "\n"))); p(selectionKey.attachment() + "\t[recieved]: " + msg + " ----->\t[send]: " + newMsg); } else { // 输入结束,关闭 socketChannel p(selectionKey.attachment() + "read finished. close socketChannel. "); socketChannel.close(); } } catch (Exception e) { // 如果read抛出异常,表示连接异常中断,需要关闭 socketChannel e.printStackTrace(); p(selectionKey.attachment() + "socket closed? "); socketChannel.close(); } } else if (selectionKey.isWritable()) { p(selectionKey.attachment() + "TODO: isWritable() ???????????????????????????? "); } else if (selectionKey.isConnectable()) { p(selectionKey.attachment() + "TODO: isConnectable() ????????????????????????? "); } else { p(selectionKey.attachment() + "TODO: else. "); } } public static void p(Object object) { System.out.println(object); } public static void main(String[] args) throws Exception { new MyFirstNIOServer(); } } 再看下客户端代码。这个客户端使用了常规的socket编程,没有使用NIO。是否使用NIO对另一方是透明的,对方看不见,也不关心。无论使用NIO还是使用常规socket,效果都是一样的,只是NIO的效率要高一些。代码为: package helloweenpad; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.util.Properties; import java.util.Random; public class MyFirstNIOClientTest extends Thread { public static final String HOST = "localhost"; public static final int PORT = 12315; boolean exist = false; Properties talks = new Properties(); Random random = new Random(); String[] keys; int messageCount = 0; public void run() { try { // 对话内容 talks.load(new FileInputStream("E:\\talk.properties")); // 客户端发送 "=" 左边的内容 keys = new String[talks.size()]; talks.keySet().toArray(keys); Socket socket = new Socket(HOST, PORT); OutputStream ous = socket.getOutputStream(); InputStream ins = socket.getInputStream(); // 接收线程,接收服务器的回应 RecieverThread reciever = new RecieverThread(ins); reciever.start(); while (!exist) { messageCount++; // 选择一个随机消息 String msg = chooseMessage(); synchronized (ins) { // 发送给服务器端 ous.write(msg.getBytes("UTF-8")); System.out.println("[send]\t" + messageCount + ": " + msg); // 然后等待接收线程 ins.wait(); } if (msg.equals("Bye")) { break; } } ins.close(); ous.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); } } public String chooseMessage() { int index = random.nextInt(keys.length); String msg = keys[index]; // 如果 10 次就选中 Bye,则重新选择,为了使对话内容多一些 if (messageCount < 10 && msg.equalsIgnoreCase("Bye")) { return chooseMessage(); } return msg; } // 接收线程 class RecieverThread extends Thread { private InputStream ins; public RecieverThread(InputStream ins) { this.ins = ins; } @Override public void run() { try { String line = null; BufferedReader r = new BufferedReader(new InputStreamReader( ins, "UTF-8")); // readLine()会阻塞,直到服务器输出一个 '\n' while ((line = r.readLine()) != null) { System.out.println("[Recieved]: " + line); synchronized (ins) { // 接收到服务器的消息,通知下主线程 ins.notify(); } if (line.trim().equals("Bye")) { exist = true; break; } } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) throws Exception { // 开三个客户端线程 for (int i = 0; i < 3; i++) { try { new MyFirstNIOClientTest().start(); } catch (Exception e) { e.printStackTrace(); } } } } ============================================================================= 服务器端的输出: Server localhost:12315 started. waiting for clients. 第 1 个客户端 [/127.0.0.1:1890]: [connected] ========================================= 第 2 个客户端 [/127.0.0.1:1865]: [connected] ========================================= 第 3 个客户端 [/127.0.0.1:1866]: [connected] ========================================= 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 我是周星驰 -----> [send]: 我是周润发 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 少小离家老大回 -----> [send]: 乡音无改鬓毛衰 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 我是客户端 -----> [send]: 我是服务器 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 我是甲 -----> [send]: 我是乙 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 我是周星驰 -----> [send]: 我是周润发 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: Hi -----> [send]: Hi 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 少小离家老大回 -----> [send]: 乡音无改鬓毛衰 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 我是甲 -----> [send]: 我是乙 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 床前明月光 -----> [send]: 疑是地上霜 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 我是客户端 -----> [send]: 我是服务器 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: Hi -----> [send]: Hi 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: Hi -----> [send]: Hi 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: 我是周星驰 -----> [send]: 我是周润发 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: 我是周星驰 -----> [send]: 我是周润发 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 举头望明月 -----> [send]: 低头思故乡 第 2 个客户端 [/127.0.0.1:1865]: [recieved]: Bye -----> [send]: Bye 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: Hi -----> [send]: Hi 第 2 个客户端 [/127.0.0.1:1865]: read finished. close socketChannel. 第 1 个客户端 [/127.0.0.1:1890]: [recieved]: Bye -----> [send]: Bye 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 我是客户端 -----> [send]: 我是服务器 第 1 个客户端 [/127.0.0.1:1890]: read finished. close socketChannel. 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: 我是客户端 -----> [send]: 我是服务器 第 3 个客户端 [/127.0.0.1:1866]: [recieved]: Bye -----> [send]: Bye 第 3 个客户端 [/127.0.0.1:1866]: read finished. close socketChannel. 客户端的输出: [send] 1: 我是周星驰 [send] 1: 少小离家老大回 [Recieved]: 乡音无改鬓毛衰 [send] 2: 床前明月光 [Recieved]: 疑是地上霜 [send] 3: 我是客户端 [Recieved]: 我是服务器 [Recieved]: 疑是地上霜 [Recieved]: 我是周润发 [Recieved]: 低头思故乡 [send] 2: 举头望明月 [Recieved]: 疑是地上霜 [send] 3: 床前明月光 [send] 1: 床前明月光 [send] 2: 举头望明月 [Recieved]: 低头思故乡 [Recieved]: 我是乙 [send] 4: 我是甲 [Recieved]: 我是周润发 [send] 5: 我是周星驰 [send] 3: 床前明月光 [send] 6: 床前明月光 [send] 4: 举头望明月 [Recieved]: 低头思故乡 [send] 5: 床前明月光 [Recieved]: 疑是地上霜 [Recieved]: 疑是地上霜 [Recieved]: 疑是地上霜 [Recieved]: Hi [send] 4: Hi [Recieved]: 低头思故乡 [send] 5: 举头望明月 [Recieved]: 低头思故乡 [Recieved]: 低头思故乡 [send] 6: 举头望明月 [send] 7: 少小离家老大回 [s |
|||
fansofjava | http://fansofjava.javaeye.com/ | ||
最近的一个项目又用到了excel导入这么个功能,虽然以前做过,但是事隔一年多,已经一年多,早忘了,看了网上的一些资料,讲得不是很到位,花了点时间整理了一下,今天有一点空,就把它记录下来: 主要用到的技术有: jxl.jar(只这一包就可以,很简单) spring jdbcTemplate 由于是批量导入,如果直接使用hibernate,效率有些低,所以直接使用jdbcTemplate,从最基本的入手: Java代码 List<Question> questions = new ArrayList<Question>(); Question question = null; try { Workbook book = Workbook.getWorkbook(new File("d:/Test.xls")); // 获得第一个sheet,默认有三个 Sheet sheet = book.getSheet(0); // 一共有多少行多少列数据 int rows = sheet.getRows(); int columns = sheet.getColumns(); boolean hasText = false; for (int i = 0; i < rows; i++) { // 过滤掉没有文本内容的行 for (int j = 0; j < columns; j++) if (sheet.getCell(j, i).getContents() != "") { hasText = true; break; } if (hasText) { question = new Question(); question.setTitle(sheet.getCell(0, i).getContents()); question.setType1(sheet.getCell(1, i).getContents()); question.setType2(sheet.getCell(2, i).getContents()); question.setType(Integer.valueOf(sheet.getCell(3, i) .getContents())); question.setScore(Integer.valueOf(sheet.getCell(4, i) .getContents())); question.setA(sheet.getCell(5, i).getContents()); question.setB(sheet.getCell(6, i).getContents()); question.setC(sheet.getCell(7, i).getContents()); question.setD(sheet.getCell(8, i).getContents()); question.setE(sheet.getCell(9, i).getContents()); question.setTrueAnswer(sheet.getCell(10, i).getContents()); questions.add(question); } } book.close(); } catch (Exception e) { e.printStackTrace(); } return questions; List<Question> questions = new ArrayList<Question>(); Question question = null; try { Workbook book = Workbook.getWorkbook(new File("d:/Test.xls")); // 获得第一个sheet,默认有三个 Sheet sheet = book.getSheet(0); // 一共有多少行多少列数据 int rows = sheet.getRows(); int columns = sheet.getColumns(); boolean hasText = false; for (int i = 0; i < rows; i++) { // 过滤掉没有文本内容的行 for (int j = 0; j < columns; j++) if (sheet.getCell(j, i).getContents() != "") { hasText = true; break; } if (hasText) { question = new Question(); question.setTitle(sheet.getCell(0, i).getContents()); question.setType1(sheet.getCell(1, i).getContents()); question.setType2(sheet.getCell(2, i).getContents()); question.setType(Integer.valueOf(sheet.getCell(3, i) .getContents())); question.setScore(Integer.valueOf(sheet.getCell(4, i) .getContents())); question.setA(sheet.getCell(5, i).getContents()); question.setB(sheet.getCell(6, i).getContents()); question.setC(sheet.getCell(7, i).getContents()); question.setD(sheet.getCell(8, i).getContents()); question.setE(sheet.getCell(9, i).getContents()); question.setTrueAnswer(sheet.getCell(10, i).getContents()); questions.add(question); } } book.close(); } catch (Exception e) { e.printStackTrace(); } return questions; 上面代码的作用就是将指定路径的excel文件放在一个List内。这个步骤比想象的的确要简单一些,居然就这么点代码就能完成excel导入java list的工作,下面进一步要做的就是,将其导入数据库,本来原来是打算用hibernate的,经过网上查找,发现都存在不少问题,于是就打算采用jdbcTemplate,而jdbcTemplate使用起来也非常的简单,首先需要配置jdbcTemplate bean,配置方法与配置hibernateTemplate差不多: Xml代码 ..... <bean id="myJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"><ref bean="dataSource"/></property> </bean> ..... ..... <bean id="myJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"><ref bean="dataSource"/></property> </bean> ..... 然后将其注入相应的dao中,就可以进入实际插入操作了: Java代码 .... public void batchInsert(final List<Question> q) { // TODO Auto-generated method stub final List<Question> questions = getQuestionsByXls(); final int size = questions.size(); String sql = "insert into question(title,type,type1,type2,state,creationTime,checked,score,a,b,c,d,e,trueAnswer) " + "values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; myJdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { public int getBatchSize() { // TODO Auto-generated method stub return size; } // i - index of the statement we're issuing in the batch, starting // from 0 public void setValues(PreparedStatement ps, int i) throws SQLException { Question question = questions.get(i); ps.setString(1, question.getTitle()); ps.setInt(2, question.getType()); ps.setString(3, question.getType1()); ps.setString(4, question.getType2()); ps.setInt(5, 1); ps.setDate(6, new Date(new java.util.Date().getTime())); ps.setInt(7, 0); ps.setInt(8, question.getScore()); ps.setString(9, question.getA()); ps.setString(10, question.getB()); ps.setString(11, question.getC()); ps.setString(12, question.getD()); ps.setString(13, question.getE()); ps.setString(14, question.getTrueAnswer()); } }); } |