I'm checking out the Play! Framework, using Java (don't want to learn a new framework and a new language at the same time - I'll incorporate Scala as I learn that), and so far it's awesome.
I'm having a bit of difficulty with forms though. I'm still stuck on the first part here and, as far as I understand, I somehow need to get an instance of FormFactory or something related, however I have no idea in which package it might be located, or whether formFactory is also another magic method (like ok).
Any pointers would be appreciated!
EDIT Here's my code:
package controllers;
import com.google.inject.Inject;
import play.data.FormFactory;
import play.api.data.Form;
import play.mvc.*;
public class User extends Controller {
#Inject
FormFactory form;
final static Form<model.User> userForm = form(model.User.class);
public Result post() {
model.User user = userForm.bindFromRequest().get();
return ok("The form was received!: " + user);
}
}
The play.data package doesn't exit for me. Maybe I did an incorrect install? To be clear, I did start this project from IntelliJ
One issue is that your form should not be static as there is no way to initialize it before FormFactory is injected.
According to docs this call
Form<model.User> userForm = form(model.User.class);
should be
Form<model.User> userForm = form.form(model.User.class)
as form is method of FormFactory.
If the package is missing from class path its some configuration issue or wrong play version. A working project can be usually obtained through activator.
Related
I'm following this simple tutorial: https://www.mkyong.com/webservices/jax-ws/jax-ws-hello-world-example-document-style/?fbclid=IwAR0vxhYrj9MKy1Q28h6luFVJoSxDP4KWBOLEu_v_Ss4uQztmB-9JuYsS4RI and at step 3 it mentions that I should receive the error:
Wrapper class com.mkyong.ws.jaxws.GetHelloWorldAsString is not found.
Have you run APT to generate them?
However, I do not get such error(no error at all) and I'm worried that it is not working as expected.
My classes:
Interface:
package com.soap3sk.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
// Service Endpoint Interface
#WebService
#SOAPBinding(style= Style.DOCUMENT, use= Use.LITERAL) // optional
public interface NoteEndpoint {
//#WebMethod ArrayList<ToDoNote> getNotes();
#WebMethod String getHelloWorldAsString(String name);
}
Implementation:
package com.soap3sk.ws;
import javax.jws.WebService;
#WebService(endpointInterface = "com.soap3sk.ws.NoteEndpoint")
public class NoteEndpointImpl implements NoteEndpoint {
#Override
public String getHelloWorldAsString(String name) {
return "Hello World JAX-WS " + name;
}
}
Publisher:
package com.soap3sk.endpoint;
import javax.xml.ws.Endpoint;
import com.soap3sk.ws.NoteEndpointImpl;
public class NoteEndpointPublisher {
public static void main (String[] args) {
Endpoint.publish("http://localhost:5000/ws/hello", new NoteEndpointImpl());
}
}
Project structure: https://imagizer.imageshack.com/img924/3514/BAuOcl.png
What I also noticed that those 2 .class files(asString and Response that are mentioned in the guide) are not generated anywhere as well. I'm using Eclipse and created a maven project with the quickstart archetype. Runnning it as a standard java application.
I can access the wsdl file going here: http://localhost:5000/ws/hello?wsdl and the I can see getHelloWorldAsString and getHelloWorldAsStringResponse there, but they are nowhere to be seen in my project and no error is thrown that they could not be found as mentioned in the guide that it should.
I also tried downloading the sample project and deleting the .java files that should be required, but it is stil the same(no error, not asking to create those classes).
I would be very grateful if someone could help. Thank you.
EDIT
I found a similiar question here: Java web service not giving error message Could someone explain his answer? Is the creation of those two classes not necessary?
you're trying to replicate a situation reported almost 10 years ago. Don't you want to try a newer tutorial like the following:
https://www.baeldung.com/jax-ws
https://spring.io/guides/gs/producing-web-service/
I am new to Java Play and am working with version 2.2.6 as I'm on a windows machine and was unable to get the newest version working correctly.
I am working through the tutorial for version 2.2.6, here, and have encountered a problem in the section called "Rendering the First Page," located approximately two thirds of the way down in the tutorial.
The tutorial shows how to make a simple "to do list" application in Java Play which has a Form where the user can submit "to do" items, which then appear on screen, and also delete them.
In "Rendering the First Page," the tutorial instructs the user to add the following code to the controller "Application.java" :
public static Result tasks(){
return ok(views.html.index.render(models.Task.all(), taskForm);
}
So, at this point, my Application.java looks like this:
package controllers;
import java.util.ArrayList;
import java.util.List;
import com.sun.javafx.tk.Toolkit.Task;
import play.*;
import play.mvc.*;
import play.data.*;
import models.*;
import views.html.*;
public class Application extends Controller {
static Form<Task> taskForm = Form.form(Task.class);
public static Result index() {
return ok("Hello World");
}
public static Result tasks() {
return ok(
views.html.index.render(models.Tasks.all(), taskForm)
);
}
public static Result newTask() {
return TODO;
}
public static Result deleteTask(Long id) {
return TODO;
}
}
Eclipse immediately underlines the word "render" in red, and I get the following error when I hover over it: "the method render(String) in the type index is not applicable for the arguments (List, Form)"
The tutorial had me create a model called Task.java, and if you look at the top of Application.java, it also had me "import com.sun.javafx.tk.Toolkit.Task," which I'm not really sure what it does.
Here's my model, Task.java:
package models;
import java.util.*;
import play.data.validation.Constraints.*;
public class Task {
public Long id;
#Required
public String label;
public static List<Task> all(){
return new ArrayList<Task>();
}
public static void create(Task task){
}
public static void delete(Long id){
}
}
So, all that being said, here's what I think the problem is:
"render"'s parameter(s) is/are defined in the view "index.scala.html", in scala
When you first create a blank Java application in java play, it auto-fills index.scala.html with the following lines of code:
#(message: String)
#main("Welcome to Play") {
#play20.welcome(message, style = "Java")
}
The tutorial had me delete all of that from index.scala.html, which like I said is a view, and had me replace it with this code:
#(tasks: List[Task], taskForm: Form[Task])
#import helper._
#main("Todo list") {
<h1>#tasks.size() task(s)</h1>
<ul>
#for(task <- tasks) {
<li>
#task.label
#form(routes.Application.deleteTask(task.id)) {
<input type="submit" value="Delete">
}
</li>
}
</ul>
<h2>Add a new task</h2>
#form(routes.Application.newTask()) {
#inputText(taskForm("label"))
<input type="submit" value="Create">
}
}
Now, the very first line in index.scala.html is what tells the controller what params "render" takes. As you can see, when you make a blank Java Play application, it starts out being #(message: String). I changed it to be #(tasks: List[Task], taskForm[Task]). So it should know that those are the params that "render" should take. But for some reason, it still thinks that "render" is supposed to take a String, and gives me an error.
I've been scouring the internet for hours and tried many solutions that have been offered before posting my own question.
Here's some things I've tried:
adding these lines to build.sbt (with spaces in between):
EclipseKeys.projectFlavor := EclipseProjectFlavor.Java
EclipseKeys.preTasks := Seq(compile in Compile)
and then closing out eclipse. from the command line in my project's directory, running "play clean-all" "play compile" "play eclipse", and then re-importing the project into eclipse.
refreshing everything in eclipse
ignoring the error and running "play debug run" and then going to localhost:9000 (one person said that this happened to them and that they just ignored the error in the IDE and that it worked fine on the server), but instead I just got the same error at localhost as I got in Eclipse, which I screen shotted:
At this point I have no idea how to proceed. My best guess like I said is that the problem is that the application for some reason doesn't "know" that I updated "index.scala.html" thereby changing the parameters that "render" takes, but I don't know why it doesn't "know" it.
Sorry this was so long; I wanted to make sure I'd included everything.
If anyone has any ideas that would be great, thank you.
in your controller you're importing a javafx Task class:
import com.sun.javafx.tk.Toolkit.Task;
but your view is expect your model class:
models.Task
change javafx Task import to models.Task import.
I'm currently going through the book GWT in Action 2nd Edition and its example code. In chapter 5 under the discussions on ClientBundle usage they have example code where there is an interface that extends com.google.gwt.rpc.client.RpcService. When I loaded this example project into my Eclipse IDE, the code shows red as the package com.google.gwt.rpc does not exist. This is most likely because I'm using GWT 2.7 and the book was written back in GWT 2.5. I attempted to look into the JavaDoc to see when it was removed, and what its replacement should be, but the only JavaDoc is for the latest, and downloads for 2.5 from the website returns no page found (404) errors. My IDE is suggesting that I change the requested interface to com.google.gwt.user.client.rpc.RemoteService but without knowing if this is the correct replacement, it seems a bit odd.
The code example they provide is as follows:
package com.manning.gwtia.ch05.client.cssresource;
import java.util.HashMap;
import java.util.List;
import com.google.gwt.rpc.client.RpcService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
#RemoteServiceRelativePath("CSSResourceService")
public interface ResourceService extends RpcService {
List<String> getThemes();
HashMap<String, String> getTheme(String name);
}
Does anyone know what the proper replacement interface for RpcService and maybe also tell me in which version it was removed?
com.google.gwt.rpc was an experiment aimed at replacing RPC from com.google.gwt.user. It didn't met expectations and was ultimately removed in 2.7. So yes, use RemoteService, like you should have actually always done.
I am having a strange sort of conflict when attempting to use the java.util.Properties class in a Play Controller, consider the following:
package controllers;
import play.mvc.*;
import java.util.*;
public class Simple extends Controller {
Properties prop = new Properties();
prop.setProperty("database", "localhost");
}
In Eclipse the setProperty method returns:
Syntax error on token(s), misplaced construct(s)
Syntax error on tokens, delete these tokens
I think there is some conflict with this code being within a Controller, the same two lines work in a simple Java class in a bespoke package.
Any help would be much appreciated, I am new Play with some Java experience.
Put these two lines inside a method block:
import play.mvc.*;
import java.util.*;
public class Simple extends Controller {
public static void pickABetterMethodName() { // Method
Properties prop = new Properties();
prop.setProperty("database", "localhost");
}
}
This will solve the syntax problem. The reason is that you can't have code that is not method or field declaration in the class declaration itself. Behavior is implemented in methods. Here's the Java Tutorial about class declaration and here the about method declaration.
I think what you're trying to do is execute code during the controller initialization. If I remember correctly, in Play 1.x this was possible with a #OnApplicationStart decorator (on a method). I'm not sure this is still the case with Play 2.x.
Edit: With Play 2.x you do this with the Application global settings.
Okay, this had been making me very mad. I've followed almost 8 tutorials all over the Internet and in the end, I got my Red5 server instance working. Good for me! But when I'm calling my Java methods in my Red5 apps from my AS3 apps, in the 'Console' window in Eclipse, I got this error :
[ERROR] [NioProcessor-1] org.red5.server.service.ServiceInvoker - Method getTheName with parameters [] not found in org.red5.core.Application#17e5fde
Here's my Application.java file.
package org.red5.core;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.service.ServiceUtils;
/**
* Sample application that uses the client manager.
*
* #author The Red5 Project (red5#osflash.org)
*/
public class Application extends ApplicationAdapter {
/** {#inheritDoc} */
#Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
return true;
}
/** {#inheritDoc} */
#Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
public String getTheName() { return "MyName!"; }
}
And here's my AS3 code. I just put this on the Timeline.
var nc:NetConnection = new NetConnection();
nc.connect("http://localhost/Mintium/RoomHere", "SomeUsernameHere");
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.objectEncoding = ObjectEncoding.AMF0;
function onNetStatus(e:NetStatusEvent):void
{
switch (e.info.code)
{
case "NetConnection.Connect.Success" :
trace("connected");
nc.call("getTheName", new Responder(getName_result, getName_error));
break;
}
}
function getName_result(res:Object):void { append("Name : " + res.toString()); }
function getName_error(res:Object):void { append(res.toString()); }
Its been a week I've been trying to figure it out and my dateline is next month. If this stuff is not solved, I'm gonna fail my assessment. Please help me with my problems. Thank you very much.
Sorry I did not see this 2 months ago, I could have helped you pass your assessment. Nevertheless, I think I can answer this question, having had a similar problem calling Red5 services.
The key to solving this problem is in those parts of Red5 that utilize the Spring Framework. In your project, there should be a file called red5-web.xml that resides in the Server project's WEB-INF folder. This file contains some Bean dependencies used by Red5's Spring components. This is not mentioned in the tutorials that I read, or even in most of the (rather sparse and distributed) red5 programming documentation.
What you have to do is add a bean entry for your method in that file. In your case, the entry should look like this:
<bean id="getTheName.service" class="org.red5.core.Application" />
Note my use of the name of your function, with ".service" appended. I do not understand why, but you need the ".service" appended in order for Red5 to find your function. You need to add a similar entry for every class whose functions you want to use as services.
Of course, I based everything I said above on the fact that you put the service into the Application class -- something which I never do. if you read the red5-web.xml file, you will see that there is already an entry for that class, because it is already injected through Spring as the class that acts as an "endpoint" for processing requests over the web. I do not know if using the Application class as an endpoint and a provider of services is a good idea (it violates "separation of concerns" in OOP and may cause problems with Spring).
What I usually do is add a separate class in the org.red5.core package (or any other package you might want) that acts to deliver the desired service, then put an entry into red5-web.xml that injects the class and its method. So, for your project, lets assume you have a class called NameProvider in the org.red5.core package:
public class NameProvider
{
public NameProvider() {}
public String getTheName() { return("MyName!"); }
}
then you add the following entry to your red5-web.xml file:
<bean id="getTheName.service" class="org.red5.core.NameProvider" />
That should make everything work.
I hope this helps you in the future, or anyone else having this problem. I just wish I'd seen this question sooner.