Play Framework - Mit params umleiten



Ich versuche herauszufinden, wie eine Umleitung innerhalb einer Controller-Aktion in Play (2.0) mit Scala durchgeführt wird.

Die Weiterleitung mit


```
<code>Redirect(routes.Application.index)
</code>
```
funktioniert gut

Was ich aus den Dokumenten, der API oder Google nicht herausfinden kann, ist, wie dem Aufruf Parameter hinzugefügt werden.

Ich komme aus Grails, wo dies leicht wie folgt gemacht werden könnte:

Weiterleitungsaktion: "Index", Parameter: ["Schlüssel": "Wert"].

Die einzige Möglichkeit, die ich gefunden habe, besteht darin, Redirect mit einer Zeichenfolge-URL und einer Abfragezeichenfolge aufzurufen, was unangenehm erscheint.

Grundsätzlich möchte ich Redirect (Call) irgendwie nutzen, aber ich kann das Call-Objekt nicht mit Reverse Routing erstellen.

Fehlt mir etwas / bekomme ich das Konzept nicht in Play / Scala?

Danke im Voraus!
Eine Route ist nur eine Funktion. Sie können also wie gewohnt Argumente übergeben:


```
<code>// Redirect to /hello/Bob
def helloBob = Action {
    Redirect(routes.Application.hello("Bob"))    
}
</code>
```
Dieser Ausschnitt stammt von<http://www.playframework.org/documentation/2.0/ScalaRouting> (unten)
<p>sie können mit <code>response.redirect()</code> von einer seite zu einer anderen umleiten.</p> <p>die standardmethode für die angabe des objekttyps ist entweder <a href="http://search.cpan.org/perldoc?perlfunc#ref"><code>ref</code></a> oder <a href="http://search.cpan.org/perldoc?scalar::util"><code>scalar::util</code></a> <code>::blessed</code>. wenn sie<em> wissen </em>das objekt gesegnet ist, geben sie dieselbe information zurück. </p><pre><code>my $class1 = blessed( $obj ); my $class2 = ref $obj; </code></pre><p><code>ref</code> gibt jedoch auch 'hash' für nicht gesegnete hashes zurück, während <code>blessed</code> dieses spiel ablehnt. </p><p>für eine liste von methoden ist es für den gesegneten zeigerstil eines perl-objekts einfach, eine davon selbst zu codieren. der folgende code funktioniert ziemlich gut für mich. es gibt die namen der funktionen (diejenigen, die den &quot;code-slot&quot; des angegebenen namens annehmen) zurück, die dem paket zugeordnet sind, das sie definiert. </p><pre><code>sub class\_methods { use class::isa; my $obj = shift; return unless ref( $obj ); my %meth\_names; foreach my $anc ( class::isa::self\_and\_super\_path( ref $obj ), 'universal' ) { my $stash = \%{"$anc\::"}; my @funcs = grep { m/^[\_\p{alpha}]/ # begins with \_ or alpha &amp;&amp; !exists $meth\_names{$\_} # no clobbering &amp;&amp; defined *{$stash-&gt;{$\_}}{code} # has a filled code slot } keys %$stash ; # assign to the "hash slice", keyed by all the entries in @funcs # the value of $anc repeated as many times as elements in @funcs. @meth\_names{@funcs} = ( $anc ) x @funcs; } return %meth\_names; } </code></pre><ul> <li><p>dies funktioniert auch für relativ komplexe objekte, aber wenn das besitzende paket eine menge generierten codes enthält, ist es nicht besonders hilfreich zu wissen, in welchem ​​paket die generatoren den code-pointer stecken. es wird mehr bedeuten, welches paket zu finden ist generiert den code. </p></li> <li><p>ist dies der fall, erhalten sie<em> might </em>den code aus der ausführung ihres codes, einschließlich <a href="http://search.cpan.org/perldoc?data::dumper"><code>data::dumper</code></a> und setzen von <code>$data::dumper::deparse</code> auf 1 wie folgt: (<code>local $data::dumper::deparse = 1;</code>) und dann den code-zeiger wie folgt: <code>say dumper( $code\_ref );</code></p></li> <li><p>es<em> won't </em>funktioniert für gültige methoden, die noch mit einer beliebigen <code>autoload</code>-methode erstellt werden müssen. wenn sie diese in der liste sehen, macht das objekt möglicherweise mehr, aber was es alles tut, wissen sie nicht.</p></li> <li><p>die &quot;basisklasse&quot; <code>universal</code> ist enthalten, da diese klasse verhalten enthält, das vom objekt verwendet werden kann. </p></li> </ul><p>viel glück.</p> <pre><code>obj = obj.getclass().getsuperclass().cast(obj); </code></pre><p>diese zeile entspricht nicht ihren erwartungen. das casting eines <code>object</code> ändert es nicht wirklich, es weist den compiler lediglich an, es als etwas anderes zu behandeln.</p><p>z.b. sie können ein <code>list</code> in ein <code>collection</code> umwandeln, es bleibt jedoch weiterhin ein <code>list</code>.</p><p>das durchlaufen der superklassen, um auf felder zuzugreifen, funktioniert jedoch ohne casting:</p><pre><code>class&lt;?&gt; current = yourclass; while(current.getsuperclass()!=null){ // we don't want to process object.class // do something with current's fields current = current.getsuperclass(); } </code></pre><p>übrigens, wenn sie zugriff auf das spring framework haben, gibt es eine praktische methode zum durchlaufen der felder einer klasse und aller übergeordneten klassen:<br> <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/reflectionutils.html#dowithfields%28java.lang.class,%20org.springframework.util.reflectionutils.fieldcallback%29"><code>reflectionutils.dowithfields(baseclass, fieldcallback)</code></a> <br> (siehe auch meine vorherige antwort: <a href="https://stackoverflow.com/a/3567968/342852">zugriff auf private geerbte felder über reflection in java</a> )</p> <p>ich würde folgendes überlegen:</p><ul> <li>möchten sie, dass ihr code aus sprachen verwendet wird, die optionale parameter nicht unterstützen? wenn ja, ziehen sie die überlastungen in betracht.</li> <li>hast du irgendwelche mitglieder in deinem team, die freiwillige parameter gewaltsam ablehnen? (manchmal ist es einfacher, mit einer entscheidung zu leben, die sie nicht mögen, als den fall zu diskutieren.)</li> <li>sind sie zuversichtlich, dass sich ihre standardwerte nicht zwischen builds ihres codes ändern, oder wenn dies der fall ist, werden ihre anrufer damit einverstanden sein?</li> </ul><p>ich habe nicht überprüft, wie die standardeinstellungen funktionieren, aber ich würde davon ausgehen, dass die standardwerte in den aufrufenden code eingebettet werden, ähnlich wie verweise auf <code>const</code>-felder. das ist normalerweise in ordnung - änderungen an einem standardwert sind sowieso ziemlich wichtig - aber das sind die dinge, die zu beachten sind.</p> <p>wie aus den aktualisierungen der ursprünglichen frage hervorgeht, konnte ich meinen code zum laufen bringen, obwohl ich com\_ajax nicht verwendet und meine eigene komponente darauf aufgebaut habe. es gab ein paar haken auf dem weg, aber durch das erstellen meiner eigenen kleinen komponente bekam ich den code so, wie ich es brauchte.</p><p>dazu musste ich der .htaccess-datei der joomla-umgebung einen cors-header hinzufügen, der die daten (site j aus meiner ursprünglichen frage) für access control allow origin (in apache: header-set access-control-allow-origin) verarbeitet. <a href="https://your.originating.site">https://your.originating.site</a> '), um zugriff auf die gehostete umgebung zu erhalten. ich bekam immer eine 301 ohne.</p><p>zuletzt möchte php eine html-datei zurückgeben. genau das tut es. der befehl exit () beendet das skript, bevor die homepage der zielwebsite für sie "zurückgegeben" wird. vielleicht ein wenig eine etwas harte herangehensweise, aber es funktioniert und wird meinen bedürfnissen entsprechen.</p><p>nochmals vielen dank an diejenigen, die geantwortet haben. es half mir, in die richtung zu weisen, die ich brauchte.</p><p>um daten an meine kleine komponente (com\_reverse) zu "pushen", habe ich ein jquery.get und ein curl get verwendet.</p><p>jquery (aus javascript, der kürze halber vereinfacht)</p><pre><code>jquery.get("https://my.joomla.site/index.php?option=com\_reverse", {"text\_str": "text string to reverse"}, function(result) { alert(result) }); </code></pre><p>curl (aus php wiederum der kürze halber vereinfacht)</p><pre><code>$ch = curl\_init(); // initialize curl $curl\_url = "https://my.joomls.site/index.php?option=com\_reverse" . "&amp;text\_str=" . urlencode("string to reverse") //curl\_setopt( $ch, curlopt\_get, 1 ); // get is the default curl\_setopt($ch, curlopt\_url, $curl\_url); curl\_setopt($ch, curlopt\_ssl\_verifyhost,0); curl\_setopt($ch, curlopt\_ssl\_verifypeer, 0); curl\_setopt($ch, curlopt\_returntransfer, 1 ); curl\_setopt($ch, curlopt\_followlocation, 1); // required for redirects $curl\_result = curl\_exec($ch); curl\_close($ch); echo "curl result: " . $curl\_result; // echos back to calling script </code></pre><p>hinweis: curl get und umleitung haben probleme. sie verlieren unterwegs die url-codierung von zeichenfolgen und ihre zeichenfolgen enden am ersten leerzeichen. dies ist für mich kein großes problem, da die meisten daten, die ich verwenden werde, numerisch sind. um dies zu überwinden, ändere ich einfach "" in "~" in meinen zeichenketten und kehre das vor dem "echo" um. wenn jemand eine möglichkeit kennt, die url-codierung über 2 oder 3 weiterleitungen aufrechtzuerhalten, würde ich gerne wissen, wie (es gibt viele curl-optionen, die ich noch nicht untersucht habe).</p><p>hinweis 2: sie sollten einige sicherheitsfunktionen integrieren, wenn sie dies tun möchten. ich werde ein paar schecks in meinen endgültigen code einfügen. dies war nur um herauszufinden, was funktionieren würde.</p> Parameter von Lambda-Ausdrücken verwenden keine auf Namen basierende Gleichheit, sie verwenden Referenzgleichheit. In Ihrem Ausdruck haben Sie also zwei völlig verschiedene Parameter namens `s` , einer ist definiert, wird aber nicht verwendet, der andere wird verwendet, aber nicht definiert. 

 Also, im Grunde ist Ihr Ausdruck etwas wie `s1 => s2 == "test"` , weshalb er nicht kompiliert werden kann. Die einfachste Lösung wäre, denselben Parameter zu verwenden, den der ursprüngliche Ausdruck verwendet: 


```
LambdaExpression lambda = Expression.Lambda(equal.Body, equal.Parameters.Single());

```
  Wenn Sie wirklich Ihren eigenen Parameter verwenden möchten, müssten Sie alle Instanzen des ursprünglichen Parameters im Lambda-Body durch Ihren neuen Parameter ersetzen. Der beste Weg dies zu tun, ist [`ExpressionVisitor`](http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor.aspx) zu verwenden. <p>byval- und byref-argumente sollten basierend auf den anforderungen und dem wissen über ihre funktionsweise verwendet werden <em>nicht</em> in bezug auf die geschwindigkeit.</p><p> <a href="http://www.developer.com/net/vb/article.php/3669066">http://www.developer.com/net/vb/article.php/3669066</a> </p><p><em>als antwort auf einen kommentar von slough -</em></p><p><strong> was verbraucht zur laufzeit mehr ressourcen? </strong></p><p>parameter werden an den stapel übergeben. der stapel ist sehr schnell, weil seine speicherzuordnung einfach ein zeigerinkrement ist, um einen neuen &quot;rahmen&quot; oder &quot;zuordnungssatz&quot; zu reservieren. die meisten .net-parameter überschreiten die größe eines maschinenregisters nicht so wenig, wenn zum übergeben von parametern ein stack-speicherplatz verwendet wird. tatsächlich werden basistypen und zeiger auf dem stack zugewiesen. die stapelgröße in .net ist auf 1 mb begrenzt. dies sollte ihnen einen eindruck davon vermitteln, wie wenig ressourcen durch die parameterübergabe verbraucht werden.</p><p>sie können diese artikelserie interessant finden:</p><p><em> <a href="http://www.atalasoft.com/cs/blogs/rickm/archive/2008/04/15/improving-performance-through-stack-allocation-net-memory-management-part-2.aspx">verbesserung der leistung durch stapelzuordnung (.net-speicherverwaltung: teil 2)</a> </em> </p><p><strong> was ist schneller? byval oder byref. </strong></p><p>es ist im besten fall schwierig, genau und fair zu messen - abhängig vom kontext ihrer messung, aber ein benchmark, den ich geschrieben habe, als er eine methode 100 millionen mal aufgerufen hat, kam zu folgendem ergebnis:</p><ul> <li>reference type - passed byref: 420 ms</li> <li>reference type - passed byval: 382 ms</li> <li>value type - passed byref: 421 ms</li> <li>value type - passed byval: 416 ms</li> </ul><pre><code>public sub method1(byref s as string) dim c as string = s end sub public sub method2(byval s as string) dim c as string = s end sub public sub method3(byref i as integer) dim x as integer = i end sub public sub method4(byval i as integer) dim x as integer = i end sub sub main() dim s as string = "hello world!" dim k as integer = 5 dim t as new stopwatch t.reset() t.start() for i as integer = 0 to 100000000 method1(s) next t.stop() console.writeline("reference type - byref " &amp; t.elapsedmilliseconds) t.reset() t.start() for i as integer = 0 to 100000000 method2(s) next t.stop() console.writeline("reference type - byval " &amp; t.elapsedmilliseconds) t.reset() t.start() for i as integer = 0 to 100000000 method3(i) next t.stop() console.writeline("value type - byref " &amp; t.elapsedmilliseconds) t.reset() t.start() for i as integer = 0 to 100000000 method4(i) next t.stop() console.writeline("value type - byval " &amp; t.elapsedmilliseconds) console.readkey() end sub </code></pre><p>die variable und die zuordnung in jeder methode auskommentieren -</p><ul> <li>reference type - passed byref: 389 ms</li> <li>reference type - passed byval: 349 ms</li> <li>value type - passed byref: 416 ms</li> <li>value type - passed byval: 385 ms</li> </ul><p>man könnte daraus schließen, dass das übergeben von referenztypen (zeichenfolgen, klassen) byval einige zeit spart. sie können auch sagen, dass die übergabe von werttypen (ganzzahl, byte) - byval etwas zeit spart.</p><p>wieder ist die zeit im großen system der dinge vernachlässigbar. wichtiger ist, byval und byref richtig einzusetzen und zu verstehen, was &quot;hinter den kulissen&quot; los ist. die in ihren routinen implementierten algorithmen beeinflussen die laufzeit ihres programms höchstwahrscheinlich um ein vielfaches.</p> <p>verwenden sie <a href="http://code.google.com/apis/maps/documentation/javascript/services.html#directions">routenplaner</a> von google maps api v3. es ist im grunde dasselbe wie das routen-api, aber in google maps api gut verpackt, was auch eine bequeme möglichkeit bietet, die route auf der karte einfach zu rendern.</p><p>informationen und beispiele zum rendern der route auf der karte finden sie in <a href="http://code.google.com/apis/maps/documentation/javascript/services.html#renderingdirections">abschnitt zum rendern der route</a> der dokumentation zu google maps api v3.</p> <p>es gibt eine verknüpfung zum navigieren in der board-ansicht, jedoch nicht von karte zu karte, während sie sie ansehen. wir werden das untersuchen, danke.</p> <p>in rails können sie ein konfigurationsobjekt erstellen und die erforderlichen informationen daraus abrufen:</p><pre><code>config = rails.configuration.database\_configuration host = config[rails.env]["host"] database = config[rails.env]["database"] username = config[rails.env]["username"] password = config[rails.env]["password"] </code></pre><p>weitere informationen finden sie in der <a href="http://api.rubyonrails.org/classes/rails/configuration.html">dokumentation</a> für rails :: configuration.</p><p>hierfür wird nur <a href="http://www.ruby-doc.org/core/classes/yaml.html">yaml :: load</a> verwendet, um die konfiguration aus der datenbankkonfigurationsdatei zu laden (<code>database.yml</code>) mit dem sie selbst informationen von außerhalb der rails umgebung abrufen können:</p><pre><code>require 'yaml' info = yaml::load(io.read("database.yml")) print info["production"]["host"] print info["production"]["database"] ... </code></pre>