【问题标题】:How to read data in JavaScript from a Java server?如何从 Java 服务器读取 JavaScript 中的数据?
【发布时间】:2019-04-15 01:09:57
【问题描述】:

我正在运行一个显示时间的简单服务器,当有人使用 telnet\putty 连接到它时,他可以看到时间。

我需要用 JavaScript 编写一个从服务器读取数据的代码。 我该怎么做?

这是服务器代码

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;




class ClientThread extends Thread {

   private final Socket _socket;

   public ClientThread( Socket socket ) {
      System.out.println( "New client" );
      _socket = socket;
      setDaemon( true );
      start();
   }

   @Override
   public void run() {
      try(
         final OutputStream outputFromServer = _socket.getOutputStream();
         final PrintWriter serverPrintOut = new PrintWriter(
            new OutputStreamWriter( outputFromServer, "utf-8" ), true ))
      {
         serverPrintOut.println( "Welcome to time server" );
         for(;;) {
            final long elapsed = System.currentTimeMillis() - MyServer.StartTime;
            serverPrintOut.println( elapsed );
            Thread.sleep( 1000L );
         }
      }
      catch( final InterruptedException ex) {/**/}
      catch( final IOException e ) {
         e.printStackTrace();
      }
   }
}

public class MyServer {

   static Calendar startTime = Calendar.getInstance();
   static long StartTime = System.currentTimeMillis();



   public static void main( String[] args ) throws IOException {
      try( ServerSocket serverSocket = new ServerSocket( 9991 )) {
         for(;;) {
            new ClientThread( serverSocket.accept());
         }
      }
   }
}

这就是我在 JavaScript 中所拥有的

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <%--<script type="text/javascript" src="jsocket.js"></script>--%>
    <%--<script type='text/javascript'>--%>
        <%--// Host we are connecting to--%>
        <%--var host = '10.0.0.82';--%>
        <%--// Port we are connecting on--%>
        <%--var port = 9991;--%>

        <%--var socket = new JSocket();--%>

        <%--// When the socket is added the to document--%>
        <%--socket.onReady = function(){--%>
            <%--socket.connect(host, port);--%>
        <%--}--%>

        <%--// Connection attempt finished--%>
        <%--socket.onConnect = function(success, msg){--%>
            <%--if(success){--%>
                <%--// Send something to the socket--%>
                <%--socket.write('Hello world');--%>
            <%--}else{--%>
                <%--alert('Connection to the server could not be estabilished: ' + msg);--%>
            <%--}--%>
        <%--}--%>
        <%--socket.onData = function(data){--%>
            <%--alert('Received from socket: '+data);--%>
        <%--}--%>

        <%--// Setup our socket in the div with the id="socket"--%>
        <%--socket.setup('mySocket');--%>
    <%--</script>--%>
    <script src="socket.io.js"></script>
    <script>
//        var socket = io('http://10.0.0.82:9991');
//        socket.on('connect', function(){});
//        socket.on('event', function(data){});
//        socket.on('disconnect', function(){});


        var socket = io('10.0.0.82:9991');
        socket.on('news', function (data) {
            console.log(data);
            socket.emit('my other event', { my: 'data' });
        });
    </script>
</head>
<body>

</body>
</html>

但是当我运行 JavaScript 代码时,我收到错误“无效的 http 响应” 我明白为什么(服务器不是http)-但是我该如何克服呢? 什么将是快速和容易的 - 更改 JavaScript 或使服务器 http ?

  • 我想补充一点,最终代码将处理 30 种类型的数据(在服务器中) - 各种传感器读数。

【问题讨论】:

  • (请记住JavaScript是一个词,这是为了避免与Java混淆)

标签: javascript java server client


【解决方案1】:

tl;博士

根据this Answer,这是解析自1970-01-01T00:00Z 的epoch reference 以来的毫秒数的JavaScript。

var date = new Date( millisecondsSinceEpochReference );

其他建议

除了 JavaScript 代码,我还可以提供一些主要建议:Java Servlet、java.time 类和 ISO 8601 格式。

Java 小服务程序

无需重新发明 Web 服务器。 Java Servlet 技术的发明是为了让这种工作变得非常简单。

编写一个返回所需字符串的简单 servlet 应用程序。只需几行代码。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet ( "/now" )
public class NowServlet extends HttpServlet {

    public void doGet ( HttpServletRequest req , HttpServletResponse res )
        throws ServletException, IOException {

        res.setContentType( "text/plain" );
        PrintWriter out = res.getWriter();

        Instant instant = Instant.now();
        String output = instant.toString();

        out.println( output );
    }
}

然后在任何符合 Servlet 的服务器(web container)上运行您的 servlet,例如 Apache TomcatEclipse Jetty

如果您愿意,您可以通过创建RESTful 网络服务来获得乐趣。

java.time

您的 Java 后端正在使用可怕的旧日期时间类,这些类在几年前已被现代 java.time 类所取代。

如果您坚持将某个时刻作为 epoch reference 的计数来跟踪,那么这里是从 1970-01-01T00:00Z 开始计算 milliseconds 的代码。

Instant.now().toEpochMilli() 

但我建议你交换文本而不是这个单纯的整数。继续阅读。

ISO 8601

以文本形式交换日期时间值时,请使用标准ISO 8601 格式。这些格式实用且有用,旨在避免歧义,并且易于机器解析,也易于跨文化的人类阅读。

java.time 类在解析/生成字符串时默认使用这些标准格式。所以不需要指定格式模式。

对于UTC 中的值,请使用Instant 类。

String output = Instant.now().toString() ;

2018-11-13T02:16:19.422836Z

您可以将这样的字符串解析回一个对象。

Instant instant = Instant.parse( "2018-11-13T02:16:19.422836Z" ) ;  

如果您的目标被限制为毫秒而不是nanosecondsjava.time 分辨率,则截断。

String output = 
    Instant
    .now()
    .truncatedTo( ChronoUnit.MILLIS )
    .toString() 
;

2018-11-13T02:18:05.333Z

可能想要交换特定地区人们使用的挂钟时间中的值(time zone)。但一般来说,最好的做法是在UTC交流时刻。

对于时区,使用ZonedDateTime 类。此类上的 toString 方法通过在方括号中附加时区名称,明智地扩展了 ISO 8601 标准。

String output = 
    ZonedDateTime                          // Represent a moment as seen through the wall-clock time used by the people of a particular region (a time zone).
    .now(                                  // Capture the current moment.
        ZoneId.of( "America/Montreal" )    // Always specify proper zone name in `Continent/Region` format, never 2-4 letter pseudo-zones such as PST, EST, CEST, or IST.
    )                                      // Returns a `ZonedDateTime` object.
    .toString()                            // Generates text in ISO 8601 format extended to append the name of zone in square brackets.

2018-11-12T21:27:54.595139-05:00[美国/蒙特利尔]

您可以将这样的字符串解析回一个对象。

ZonedDateTime zdt = ZonedDateTime.parse( "2018-11-12T21:27:54.595139-05:00[America/Montreal]" ) ;

如果需要,如上所示截断。


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2016-12-25
    相关资源
    最近更新 更多