Setting up a basic scala program on a server - http

As an experiment in scala I want to set up a basic website with scala as a server side language. This would not carry out many interactive tasks - it would simply write and distribute HTML in response to HTTP requests.
I don't know much about how the piping of web servers works, but I've written lots of HTML, CSS, JS and PHP and I envisage this working much like the PHP back end in wordpress - the client sends an HTTP request for a page such as example.wordpress.com/2012/06/18/example_blog and the PHP on the server compiles an HTML web page and returns it to the user.
Although I'm open to suggestions, I'd rather not use a full blown framework such as Lift as I'm trying to build from the ground up. I'm only interested in the very basic task of taking an HTTP request as input and outputting an HTTP response.

Usually you'd take a Java EE server and implement a Servlet.
Here is one:
package myservlet
import javax.servlet.http._
class Servlet extends HttpServlet {
/** Servlet's main method. */
protected def welcome (request: HttpServletRequest, response: HttpServletResponse): Unit = {
response.getWriter.write ("hi")
}
override def doGet (request: HttpServletRequest, response: HttpServletResponse): Unit = welcome (request, response)
override def doPost (request: HttpServletRequest, response: HttpServletResponse): Unit = welcome (request, response)
}
Then you'd mention it in web.xml as usual:
<servlet><servlet-name>MyServlet</servlet-name>
<servlet-class>myservlet.Servlet</servlet-class></servlet>
<servlet-mapping><servlet-name>MyServlet</servlet-name>
<url-pattern>/</url-pattern></servlet-mapping>
Refer to any Java Servlet tutorial for details.

You may not want to deal with Java EE and the whole servlet thing, especially if you don't come from the "Java world".
There are some really lightweight HTTP toolkits in Scala like Blueeyes or Play mini but my favorite is definitely Unfiltered
EDIT: A more complete answer on this thread Scala framework for a Rest API Server?

Related

How to track the HTTP request and response time in jetty

I am trying to track the HTTP request and response time in Jetty. I have extended the jetty server and i am able to get the request timestamp using following snippet :
public void handle(HttpChannel connection) throws IOException,
ServletException {
super.handle(connection);
connection.getRequest().getTimeStamp();
}
I need to get the exact time of the response for the request.
How can i achieve it by extending jetty server ?
If any way of doing other than extending jetty. please let me know
Thank you
Since you seem to only be interested in the latency, do this.
The RequestLog mechanism is now to do this.
Instantiate a new RequestLogHandler and add it as the root of your server Handler tree (think nested, not collection).
Add a custom implementation of RequestLog to the RequestLogHandler
In your custom RequestLog.log(Request,Response) method, grab the Request.getTimeStamp() and work out the latency.
This approach is more durable to changes internally in Jetty, and does not require a fork Jetty + modify approach to work.

Where to hook up authentication in Grizzly?

I'm using a Grizzly HttpServer which has two HttpHandler instances registered:
under /api/* there is an Jersey REST - style application offering the API of the product, and
under /* there is an StaticHttpHandler which serves static HTML / JavaScript content (which, among other things, talks to the API under /api/
For authentication I'm currently securing only the API using a Jersey ContainerRequestFilter implementing HTTP Basic Auth, which looks quite similar to what is presented in another SO question.
But as requirements changed, now I'd like to require authentication for all requests hitting the server. So I'd like to move the authentication one level up, from Jersey to Grizzly. Unfortunately, I'm completely lost figuring out where I can hook up a "request filter" (or whatever it is called) in Grizzly. Can someone point me to the relevant API to accomplish this?
The easiest solution would leverage the Grizzly embedded Servlet support.
This of course would mean you'd need to do a little work to migrate your current HttpHandler logic over to Servlets - but that really shouldn't be too difficult as the HttpHandler API is very similar.
I'll give some high level points on doing this.
HttpServer server = HttpServlet.createSimpleServer(<docroot>, <host>, <port>);
// use "" for <context path> if you want the context path to be /
WebappContext ctx = new WebappContext(<logical name>, <context path>);
// do some Jersey initialization here
// Register the Servlets that were converted from HttpHandlers
ServletRegistration s1 = ctx.addServlet(<servlet name>, <Servlet instance or class name>);
s1.addMapping(<url pattern for s1>);
// Repeat for other Servlets ...
// Now for the authentication Filter ...
FilterRegistration reg = ctx.addFilter(<filter name>, <filter instance or class name>);
// Apply this filter to all requests
reg.addMapping(null, "/*");
// do any other additional initialization work ...
// "Deploy" ctx to the server.
ctx.deploy(server);
// start the server and test ...
NOTE: The dynamic registration of Servlets and Filters is based off the Servlet 3.0 API, so if you want information on how to deal with Servlet listeners, init parameters, etc., I would recommend reviewing the Servlet 3.0 javadocs.
NOTE2: The Grizzly Servlet implementation is not 100% compatible with the Servlet specification. It doesn't support standard Servlet annotations, or deployment of traditional Servlet web application archive deployment.
Lastly, there are examples of using the embedded Servlet API here
The "hookup" part can be done using a HttpServerProbe (tested with Grizzly 2.3.5):
srv.getServerConfiguration().getMonitoringConfig().getWebServerConfig()
.addProbes(new HttpServerProbe.Adapter() {
#Override
public void onRequestReceiveEvent(HttpServerFilter filter,
Connection connection, Request request) {
...
}
#Override
public void onRequestCompleteEvent(HttpServerFilter filter,
Connection connection, Response response) {
}
});
For the "linking" to the ContainerRequestFilter you might want to have a look at my question:
UnsupportedOperationException getUserPrincipal

Spring MVC gives HTTP 406 for application/octet-stream

I am using Spring Web MVC and have written a controller that shall return binary data to a plugin in a web-page that show 3D content. This plugin uses STK files for it's models, so I have set-up my webapp to produce this kind of contents for *.stk URLs
The springDispatcherServlet is setup to handle *.stk requests in my web.xml
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>*.stk</url-pattern>
</servlet-mapping>
My controller looks like this:
#Controller
#RequestMapping(value="/3dobject", produces="application/octet-stream")
public class Object3DController {
#Autowired
private DesignerService designerService;
#RequestMapping(value="/{article}.stk", method=RequestMethod.GET, headers="Accept: application/octet-stream")
public void getObject3DForArticle(HttpServletResponse response, #PathVariable String article) throws IOException {
response.setContentType("application/octet-stream");
Object3D object = designerService.get3DModelForArticleNumber(article, LanguageCode.NORWEGIAN);
byte[] content = object.getContent();
response.setContentLength(content.length);
IOUtils.write(content, response.getOutputStream());
}
}
When I try to access the data through a browser, I get the following error:
HTTP Status 406 - The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
I have deployed my app to a tomcat server on localhost.
Any ideas of what I must do to make the browser download the binary data?
PS! I changed from *.3do (3d object) to *.stk. With 3do it worked as expected, but the plugin fails with an error (which is hard to interpret), so I have to experiment in order to verify wether or not the URL extension matters...
The RequestMapping.produces() narrows the request and therefore is
only mapped if the Accept matches one of these media types
So you need to set the corresponding Accept header in the request from the plugin. This cannot be done by simply making an HTTP GET Request by typing in a URL into a browser. One plugin I find useful for Chrome is the Advanced REST Client. There are plenty of others that offer similar functionality. Alternatively try using cURL to make the request with the correct header.

HTTP requests in a PlayN project

I want to use RequestBuilder to make HTTP requests in my PlayN project as described here:
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideHttpRequests
I added the tag in my module xml file:
but I still have the following compilation error:
The import com.google cannot be resolved
Is there something else I should do to make my project compile?
Here is the code:
import com.google.gwt.http.client.*;
...
String url = "http://www.myserver.com/getData?type=3";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP violation, etc.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
} else {
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
If you're using Maven for your build (which I suspect you may be), make absolutely sure that the following dependency is in your html/pom.xml
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
You might need to change the version if you're using a version of GWT other than 2.4.0
Edit: Now that I know you are running a Java application (based on the comments below) and not a GWT application, you're likely going to need to make HTTP requests with something other than GWT's HTTP client. You'll want to remove the aforementioned dependency and take a look at the answers to this question for some insight into how to do that...
If you're needing to make HTTP requests in both the GWT and Java PlayN targets, you're likely going to need to abstract the HTTP client interface needed in the core module and provide the appropriate concrete implementations in the java and GWT modules. I describe using Gin and Guice to inject java and GWT specific instances of AsyncService<> objects in this answer here, and a similar approach can be used in injecting the appropriate HTTP client instance required on a per platform basis if necessary...

What is the query string of a BlazeDS request?

I have a Tomcat service running on localhost:8080 and I have installed BlazeDS. I created and configured a simple hello world application like this...
package com.adobe.remoteobjects;
import java.util.Date;
public class RemoteServiceHandler {
public RemoteServiceHandler()
{
//This is required for the Blaze DS to instantiate the class
}
public String getResults(String name)
{
String result = “Hi ” + name + “, the time is : ” + new Date();
return result;
}
}
With what query string can I invoke RemoteServiceHandler to my Tomcat instance via just a browser? Something like... http://localhost:8080/blazeds/?xyz
Unfortunately you can't. First the requests (and responses) are encoded in AMF and second I believe they have to be POSTs. If you dig through the BlazeDS source code and the Flex SDK's RPC library you can probably figure out what it's sending. But AFAIK this hasn't been documented anywhere else.
I think that AMFX (which is AMF in XML) will work for you, using HTTPChannel instead of AMFChannel.
From http://livedocs.adobe.com/blazeds/1/blazeds_devguide/help.html?content=lcarch_2.html#1073189, Channels and channel sets:
Flex clients can use different channel
types such as the AMFChannel and
HTTPChannel. Channel selection depends
on a number of factors, including the
type of application you are building.
If non-binary data transfer is
required, you would use the
HTTPChannel, which uses a non-binary
format called AMFX (AMF in XML). For
more information about channels, see
Channels and endpoints.
This way you can use simple netcat to send the request.
Not sure how authentication will be handled though, you will probably need do a login using Flash, extract the authentication cookie and then submit it as part of your request.
Please update this thread once you make progress so that we all can learn.

Resources