REST api无法提升数据?

时间:2015-10-29 17:09:25

标签: scala rest lift

我正在尝试关注Lift Web App Cookbook:

中的REST api示例

(该项目可以在github上找到:https://github.com/kindlychung/liftrestapi

客户端模型:

package code.model
import net.liftweb.json.JsonDSL._


case class Client(id: Int, name: String, email: String) {
  def asJson = {
    ("id" -> id) ~
      ("name" -> name) ~
      ("email" -> email)
  }
}

客户数据存储:

package code.session
import code.model.Client

object ClientCache {
  var clients: List[Client] = Nil

  def startClient(): Unit = {
    if (clients.isEmpty) clients = (1 to 10).toList.map(
      i => Client(i, "Client " + i, "client_" + i + "@email.com")
    )
  }
}

休息服务提供商:

package code.rest

import net.liftweb.http.rest.RestHelper
import net.liftweb.http._
import net.liftweb.json.JsonDSL._
import net.liftweb.util.Helpers._
import code.session.ClientCache

/**
 * Created by IDEA on 29/10/15.
 */
object Clients extends RestHelper {
  serve({
    case Req("api" :: "clients" :: Nil, _, GetRequest) => listClients()
  })

  def listClients(): LiftResponse = JsonResponse("clients" -> ClientCache.clients.map(_.asJson))
}

初始化客户端数据并启动REST API:

package bootstrap.liftweb


import net.liftweb._
import util._
import Helpers._

import common._
import http._
import sitemap._
import Loc._
import net.liftmodules.JQueryModule
import net.liftweb.http.js.jquery._
import net.liftweb.common.Logger
import code.rest.Clients
import code.session.ClientCache


/**
 * A class that's instantiated early and run.  It allows the application
 * to modify lift's environment
 */
class Boot extends Logger {
  def boot {
    // where to search snippet
    LiftRules.addToPackages("code")

    ClientCache.startClient()

    LiftRules.statelessDispatch.append(Clients)

    val canManage_? = If(
      // always true means everybody can manage
      () => {
        true
      },
      // if false, redirect to root
      () => RedirectResponse("/"))

    val isAdmin_? = If(
      // always false means nobody is admin
      () => {
        false
      },
      // if false, redirect to /contacts/list
      () => RedirectWithState("/contacts/list", MessageState("Authorized personnel only" -> NoticeType.Warning)))

    // Build SiteMap
    val entries = List(
      Menu.i("Home") / "index", // the simple way to declare a menu
      Menu.i("List contacts") / "contacts" / "list" >> canManage_?,
      Menu.i("Create") / "contacts" / "create" >> canManage_?,
      Menu.i("Edit") / "contacts" / "edit" >> canManage_?,
      Menu.i("Delete") / "contacts" / "delete" >> canManage_?,
      Menu.i("View") / "contacts" / "view" >> canManage_?,
      Menu.i("Send email") / "contacts" / "send",

      // more complex because this menu allows anything in the
      // /static path to be visible
      Menu(Loc("Static", Link(List("static"), true, "/static/index"),
        "Static Content")))

    // set the sitemap.  Note if you don't want access control for
    // each page, just comment this line out.
    LiftRules.setSiteMap(SiteMap(entries: _*))

    //Show the spinny image when an Ajax call starts
    LiftRules.ajaxStart =
      Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)

    // Make the spinny image go away when it ends
    LiftRules.ajaxEnd =
      Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)

    // Force the request to be UTF-8
    LiftRules.early.append(_.setCharacterEncoding("UTF-8"))

    //Init the jQuery module, see http://liftweb.net/jquery for more information.
    LiftRules.jsArtifacts = JQueryArtifacts
    JQueryModule.InitParam.JQuery = JQueryModule.JQuery191
    JQueryModule.init()

  }

}

从客户端访问api:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Home</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript">
      $(document).ready(function() {
                  $.ajax({
                      url: "/api/clients",
                      contentType: "application/json"
                  }).done(function(data) {
                          var clients = "";
                          $.each(data.clients, function(i, client) {
                                  clients += '<tr>' +
                                      '<td>' + client.ed + '</td><td>' + client.name + '</td><td>' + 'client.email' + '</td><td>' + 'view' + '</td><td>' + 'delete' + '</td>'
                              }
                          });
                          $tbody.html(clients);
                  };

</script>
</head>
<body data-lift-content-id="main">
<div id="main" data-lift="surround?with=default;at=content">
    <h2>Welcome to your project!!!!!</h2>

    <p>
        <span data-lift="HelloWorld.howdy">
          Welcome to your Lift app at <span id="time">Time goes here</span>
        </span>
    </p>

    <div data-lift="Calculator.plus">
        2 + 2 = <span id="result">some number</span>
    </div>

    <table>
        <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Email</th>
            <th>View</th>
            <th>Delete</th>
        </tr>
        </thead>
        <tbody></tbody>
    </table>

</div>


</body>
</html>

根据这本书,我应该在刷新浏览器后看到类似的内容:

enter image description here

但我只看到表格的标题。这里出了什么问题?

build.sbt:

name := "Lift 2.6 starter template"

version := "0.0.4"

organization := "net.liftweb"

scalaVersion := "2.11.2"

resolvers ++= Seq("snapshots"     at "https://oss.sonatype.org/content/repositories/snapshots",
                "releases"        at "https://oss.sonatype.org/content/repositories/releases"
                )

seq(webSettings :_*)

unmanagedResourceDirectories in Test <+= (baseDirectory) { _ / "src/main/webapp" }

scalacOptions ++= Seq("-deprecation", "-unchecked")

libraryDependencies ++= {
  val liftVersion = "2.6.2"
  Seq(
    "net.liftweb"       %% "lift-webkit"        % liftVersion        % "compile",
    "net.liftmodules"   %% "lift-jquery-module_2.6" % "2.8",
    "org.eclipse.jetty" % "jetty-webapp"        % "8.1.7.v20120910"  % "container,test",
    "org.eclipse.jetty" % "jetty-plus"          % "8.1.7.v20120910"  % "container,test", // For Jetty Config
    "org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "container,test" artifacts Artifact("javax.servlet", "jar", "jar"),
    "ch.qos.logback"    % "logback-classic"     % "1.0.6",
    "org.specs2"        %% "specs2"             % "2.3.12"           % "test"
  )
}

更新

我还尝试了Lift cookbook:

中的另一个例子
package code.rest

import net.liftweb.http.rest.RestHelper
import net.liftweb.http.LiftRules

object IssuesService extends RestHelper {

  def init() : Unit = {
    LiftRules.statelessDispatch.append(IssuesService)
  }

  serve("issues" / "by-state" prefix {
    case "open" :: Nil XmlGet _ => <p>None open</p>
    case "closed" :: Nil XmlGet _ => <p>None closed</p>
    case "closed" :: Nil XmlDelete _ => <p>All deleted</p>
  })
}

使用以下命令将其连接到Boot.scala:

import code.rest.IssuesService
IssuesService.init()

预期结果:

curl -H 'Content-Type: application/xml' http://localhost:8080/issues/by-state/open

<?xml version="1.0" encoding="UTF-8"?>
<p>None open</p>

观察结果:

curl -H 'Content-Type: application/xml' http://localhost:8080/issues/by-state/open
<!DOCTYPE html>
<html> <body>The Requested URL /issues/by-state/open was not found on this server</body> </html>

WEB-INF / web.xml的内容:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<filter>
  <filter-name>LiftFilter</filter-name>
  <display-name>Lift Filter</display-name>
  <description>The Filter that intercepts lift calls</description>
  <filter-class>net.liftweb.http.LiftFilter</filter-class>
</filter>


<filter-mapping>
  <filter-name>LiftFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

1 个答案:

答案 0 :(得分:0)

通过修改Clients.scala这样的文件来解决问题:

package code.rest

import code.model.Client
import net.liftweb.http.rest.RestHelper
import net.liftweb.http._
import net.liftweb.json.JsonDSL._
import net.liftweb.util.Helpers._

/**
 * Created by IDEA on 29/10/15.
 */
object Clients extends RestHelper {
  var clients = (1 to 10).toList.map(
    i => Client(i, "Client " + i, "client_" + i + "@email.com")
  )

  def init: Unit = {
    LiftRules.statelessDispatch.append(Clients)
  }

  serve(List("clients") prefix {
    case Nil XmlGet _ => listClients()
  })

  def listClients(): LiftResponse = JsonResponse("clients" -> clients.map(_.asJson))
}

我仍然不太清楚为什么原版本没有用。