Можете ли вы назначить ключ для ввода чего-либо и как [дублировать]

Для обработки клиентской части существует довольно много ответов, но вы можете изменить выходную серверную сторону, если хотите.

Есть несколько способов приблизиться к этому, я начну с основы. Вам придется подклассифицировать класс JsonResult и переопределить метод ExecuteResult. Оттуда вы можете использовать несколько разных подходов для изменения сериализации.

Подход 1: Реализация по умолчанию использует JsonScriptSerializer . Если вы посмотрите на документацию, вы можете использовать метод RegisterConverters для добавления пользовательских JavaScriptConverters . Есть несколько проблем с этим: JavaScriptConverter сериализуется в словаре, то есть он берет объект и сериализуется в Json-словаре. Чтобы сделать сериализацию объекта строкой, он требует немного хакерства, см. [D2] post .

  public class CustomJsonResult: JsonResult {private const string _dateFormat = "yyyy-MM-dd HH: mm: ss";  public override void ExecuteResult (Контекст ControllerContext) {if (context == null) {throw new ArgumentNullException ("context");  } HttpResponseBase response = context.HttpContext.Response;  if (! String.IsNullOrEmpty (ContentType)) {response.ContentType = ContentType;  } else {response.ContentType = "application / json";  } if (ContentEncoding! = null) {response.ContentEncoding = ContentEncoding;  } if (Data! = null) {JavaScriptSerializer serializer = новый JavaScriptSerializer ();  // Используйте свой подклассу JavaScriptConverter здесь.  serializer.RegisterConverters (новый JavascriptConverter [] {новый CustomConverter});  Response.Write (serializer.Serialize (данные));  }}}  

Подход 2 (рекомендуется): Второй подход - начать с переопределенного JsonResult и перейти с другим сериализатором Json, в моем случае Json.NET сериализатор. Это не требует взлома подхода 1. Вот моя реализация подкласса JsonResult:

  public class CustomJsonResult: JsonResult {private const string _dateFormat = "yyyy-MM-dd HH: mm  : сс ";  public override void ExecuteResult (Контекст ControllerContext) {if (context == null) {throw new ArgumentNullException ("context");  } HttpResponseBase response = context.HttpContext.Response;  if (! String.IsNullOrEmpty (ContentType)) {response.ContentType = ContentType;  } else {response.ContentType = "application / json";  } if (ContentEncoding! = null) {response.ContentEncoding = ContentEncoding;  } if (Data! = null) {// Использование сериализатора Json.NET var isoConvert = new IsoDateTimeConverter ();  isoConvert.DateTimeFormat = _dateFormat;  response.Write (JsonConvert.SerializeObject (данные, isoConvert));  }}}  

Пример использования:

  [HttpGet] public ActionResult Index () {return new CustomJsonResult {Data = new {users = db.Users.  К списку();  }};  }  

Дополнительные кредиты: Джеймс Ньютон-Кинг

87
задан Thomas Ahle 9 April 2014 в 12:25
поделиться

5 ответов

То, что вы хотите сделать, это перевести консоль в «сырой» режим (редактирование строки исключено и не требуется вводить ключ) в отличие от «приготовленного» режима (редактирование строки с требуемым ключом ввода). В системах UNIX «stty» 'команда может изменять режимы.

Теперь, относительно Java ... см. Неблокирующий вход консоли в Python и Java . Выдержка:

Если ваша программа должна быть на основе консоли, вам нужно переключить свой терминал из линейного режима в режим символов и не забудьте восстановить его до выхода вашей программы. Нет портативного способа сделать это в разных операционных системах.

Одним из предложений является использование JNI. Опять же, это не очень портативно. Другое предложение в конце потока, и вместе с вышеприведенным сообщением, это посмотреть на использование jCurses .

50
ответ дан stkent 15 August 2018 в 14:28
поделиться
  • 1
    JCurses не очень портативен ... Из JCurses README: «JCurses состоит из двух частей: независимой от формы матрицы и части, зависящей от формы, которая состоит из собственной разделяемой библиотеки, которая делает примитивные операции ввода и вывода доступными для первого часть & Quot. – Ryan Fernandes 1 July 2009 в 04:19
  • 2
    @RyanFernandes звучит довольно переносимо для меня - единственный инструмент, который можно запускать на нескольких системах (используя разные зависимости) – Antoniossss 19 October 2017 в 21:56

Я написал класс Java RawConsoleInput , который использует JNA для вызова функций операционной системы Windows и Unix / Linux.

  • Вкл. Windows использует _kbhit() и _getwch() из msvcrt.dll.
  • В Unix он использует tcsetattr() для переключения консоли в неканонический режим, System.in.available(), чтобы проверить, доступны ли данные и System.in.read(), чтобы читать байты с консоли. A CharsetDecoder используется для преобразования байтов в символы.

Он поддерживает неблокирующий входной и смешанный режим raw и обычный вход в линейный режим.

9
ответ дан Christian d'Heureuse 15 August 2018 в 14:28
поделиться
  • 1
    Насколько сильно это было проверено / проверено на стресс? – Nic Hartley 15 May 2016 в 05:01
  • 2
    @QPaysTaxes Стресс-тестирование сложно для ввода в консоль. Я думаю, в этом случае было бы более важно протестировать его в различных средах (разные версии для Windows / Linux, 64/32 бит, Linux через SSH, Telnet, последовательный порт или настольную консоль и т. Д.). Пока я использую его только в своих личных тестовых инструментах. Но исходный код относительно невелик по сравнению с другими решениями (например, JLine2, который использует Jansi). Так что не так много может пойти не так. Я написал это, потому что JLine2 не поддерживает одиночный ввод символов без блокировки. – Christian d'Heureuse 15 May 2016 в 23:04
  • 3
    Это то, что я имел в виду под напряжением - это, вероятно, неправильное слово; моя вина. Во всяком случае, хорошо! Я украл H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H H – Nic Hartley 15 May 2016 в 23:19
  • 4
    Эй, этот класс выглядит великолепно. Однако: я не могу заставить его работать. Как я должен его использовать? Я столкнулся с блокировкой System.in, пока не нажму CTRL + D (на Linux), и теперь я читаю о консольных режимах и подобных. Я думаю, что ваш RawConsoleInput - это то, что я ищу, но как его использовать? – Igor 25 August 2016 в 07:48
  • 5
    @Igor Просто вызовите RawConsoleInput.read (boolean), чтобы прочитать символ клавиатуры. Он задокументирован в исходном коде (RawConsoleInput.java). – Christian d'Heureuse 26 August 2016 в 15:27

Используйте jline3 :

Пример:

Terminal terminal = TerminalBuilder.builder()
    .jna(true)
    .system(true)
    .build();

// raw mode means we get keypresses rather than line buffered input
terminal.enterRawMode();
reader = terminal .reader();
...
int read = reader.read();
....
reader.close();
terminal.close();
4
ответ дан Pod 15 August 2018 в 14:28
поделиться
  • 1
    Я обнаружил, что решения на основе RawConsoleInput не работают на MacOS High Sierra; однако это прекрасно работает. – RawToast 14 April 2018 в 21:30
  • 2
    В jline есть практически все, что вам нужно для создания интерактивной консоли / терминальной системы. Он отлично работает в Linux. Для более полного примера посмотрите: github.com/jline/jline3/blob/master/builtins/src/test/java/org/… . Он имеет автозаполнение, историю, маску пароля и т. Д. – lepe 26 June 2018 в 07:28

Нет портативного способа чтения необработанных символов с консоли Java.

Некоторые связанные с платформой обходные решения были представлены выше. Но чтобы быть действительно портативным, вам придется отказаться от консольного режима и использовать режим окон, например. AWT или Swing.

14
ответ дан rustyx 15 August 2018 в 14:28
поделиться
  • 1
    Я не совсем понимаю, почему, например, у Mono (или CLR) есть System.Console.ReadKey, который работает на всех платформах. Java также распространяет JVM и JRE для каждой платформы с зависимыми от платформы библиотеками и реализациями, поэтому это не оправдание. – Martin Macak 7 March 2015 в 18:29

Вам нужно сбить консоль в сырой режим. Там нет встроенного независимого от платформы способа добраться туда. jCurses может быть интересным.

В системе unix это может работать:

    String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"};
    Runtime.getRuntime().exec(cmd).waitFor();

Например, если вы хотите принять во внимание время между нажатиями клавиш, вот пример кода, чтобы попасть туда.

20
ответ дан Xavi López 15 August 2018 в 14:28
поделиться
  • 1
    Работал отлично для меня под Linux – MrSmith42 20 October 2015 в 18:03
  • 2
    Работал и на Mac. Вы, вероятно, захотите упомянуть, что stty cooked </dev/tty следует запускать, когда программа должна вернуться в буферный режим и, безусловно, перед выходом программы. – Kelvin 8 May 2017 в 20:21
  • 3
    «Например ...» ссылка теперь мертва. – Olivier Grégoire 30 October 2017 в 13:33
Другие вопросы по тегам:

Похожие вопросы: