Scala 从Gatling表达式中提取字符串

Scala 从Gatling表达式中提取字符串,scala,vaadin,gatling,Scala,Vaadin,Gatling,我想写一个函数来格式化Vaadin消息。这些消息具有相同的格式 108|0ff1255e-e2be-4e7b-ac5c-1ff2709ce886[["0_11_12_13_login_username","v","v",["text",["s","Agent00232"]]]] 第一个数字是长度,然后是某种会话id,后来称为vaadin_security_key,后跟有效负载。在本例中,我将值Agent00232设置为连接器id为0_11_12_13_login_用户名的文本字段,我编写了如下

我想写一个函数来格式化Vaadin消息。这些消息具有相同的格式

108|0ff1255e-e2be-4e7b-ac5c-1ff2709ce886[["0_11_12_13_login_username","v","v",["text",["s","Agent00232"]]]]
第一个数字是长度,然后是某种会话id,后来称为vaadin_security_key,后跟有效负载。在本例中,我将值Agent00232设置为连接器id为0_11_12_13_login_用户名的文本字段,我编写了如下函数:

 def sendMessage(name: String, vaadinCommand: String) = {
    def createMessage(session: Session) = {
      val message = session("vaadin_security_key").as[String] + "\u001d" + vaadinCommand
      val message2 = ELCompiler.compile(message)(classTag[String])(session).toString
      val message3 = message2.substring(8, message2.length - 2)
      val len = message3.length
      val completeMessage = len.toString() + "|" + message3
      completeMessage
    }
    exec(
      ws(name)
        .sendText(createMessage)
        .check(wsAwait
          .within(Vaadin.defaultTimeout)
          .until(1)
          .regex("""(.+)""")
          .saveAs("lastResult")))
      .exec { session =>
        println(session("lastResult").as[String])
        session
      }
  }
我希望像这样使用此方法,并在字符串中使用EL表达式:

exec(Vaadin.sendMessage("setting Name", "[[\"0_11_12_13_login_username\",\"v\",\"v\",[\"text\",[\"s\",\"${username}\"]]]]"))
因此,我必须在计算长度之前计算字符串。方法ELCompiler.compile。。。返回表达式[字符串]。问题是我需要这个字符串,并用计算出的长度对其进行压缩。当我执行message2.toString时,它会返回 成功0FF1255E-e2be-4e7b-ac5c-1ff2709ce886[[0_11_12_13_登录_用户名,v,v,[text,[s,Agent00232]]],因此我必须使用子字符串8,message2.length-2获得评估的有效负载,并使用安全密钥计算其长度

有没有比使用子字符串更好更优雅的方法从表达式中提取字符串

不要显式地将类标记传递给ELCompiler.compile。如果您真的要自己使用它,请使用ELCompiler.compile[String]。 ELCompiler.compile返回一个表达式[String],将会话的函数别名为Validation[String],因此如果应用它,将得到一个Validation[String],因为求值可能失败,因此toString将打印成功,而不是它包含的值。您需要的是映射此验证容器。 每次执行函数时,都会反复编译表达式。将其移到函数外部。 请注意,如果无法保存lastResult,sessionlastResult.as[String]将崩溃。改用validate。 使用三重引号,这样就不必转义内部的双引号。 然后,代码的第一部分将如下所示:

import io.gatling.core.session._
import io.gatling.core.session.el._

def sendMessage(name: String, vaadinCommand: String) = {

  val message = ("${vaadin_security_key}\u001d" + vaadinCommand).el[String]

  def createMessage = message.map { resolvedMessage =>
    resolvedMessage.length + "|" + resolvedMessage
  }

  exec(
    ws(name)
      .sendText(createMessage)
      .check(wsAwait
        .within(Vaadin.defaultTimeout)
        .until(1)
        .regex("""(.+)""")
        .saveAs("lastResult")))
    .exec { session =>
      println(session("lastResult").validate[String])
      session
    }
}
然后,你可以用以下方式来称呼它:

exec(Vaadin.sendMessage("setting Name", """[["0_11_12_13_login_username","v","v",["text",["s","${username}"]]]]"""))

您向我展示了一种更优雅的方法来编写方法createMessage,但您没有回答是否有更好的方法从表达式[String]中提取消息的问题,因为在我回答时,您没有正确解释为什么必须执行这样的子字符串。既然你这么做了,我明白了。编辑我的答案。