I'm using Restlet to make a RESTful platform. I haven't used it before, but I decided to use 2.0 because it is better to start with the latest and greatest technology, right?
The key thing I am looking for is the ability to have someone to put in a URL like http://mysite/New%20York/3 and have the service respond with something like [New York,New York,New York], so I need to pass in request attributes. Using this post for Restlet 1.1 (because I can't seem to find any documentation for this on the Restlet site), I wired up my application like so:
router.attach("{text}/{count}", RepeaterResource.class);
The new way to do this is apparently in the UniformResource#doInit() method, so mine looks like (without error checking):
#Override
public void doInit()
{
magicText = "" + getRequestAttributes().get("text");
repeatAmount = Integer.parseInt("" + getRequestAttributes().get("count"));
}
The problem is that the Map<String, Object> returned from getRequestAttributes() is always completely empty! This seems rather odd. Am I wiring the routing up wrong?
Of course, I could just use getQuery() and parse it myself, but that is definitely the wrong way to go about doing this and it seems like there should be an easy way to do this (similar to the way previous versions worked).
My problem, is seems, is that router attachments must start with the / character. I should attached like so:
router.attach("/{text}/{count}", RepeaterResource.class);
I can't seem to find this behavior documented and it seems rather odd, but it certainly fixed my issues.
You can do this with 2.0 the same way as with 1.1.
See the tutorial, part 11: http://www.restlet.org/documentation/2.0/tutorial#part11
Restlet is great, BTW.
Related
I am trying to create a contract for a GET request and I'd like to use a path parameter, that can be reused in the response as well. Is this at all possible? I can only find examples for POST, query parameters and body's.
So if I want to define a contract that requests an entity i.e. /books/12345-6688, I want to reuse the specified ID in the response.
How do I create a contract for something like this?
Possible since Spring Cloud Contract 1.2.0-RC1 (fixed in this issue).
response {
status 200
body(
path: fromRequest().path(),
pathIndex: fromRequest().path(1) // <-- here
)
}
See the docs.
Nope that's not possible due to https://github.com/tomakehurst/wiremock/issues/383 . Theoretically you could create your own transformer + override the way stubs are generated in Spring Cloud Contract. That way the WireMock stubs would contain a reference to your new transformer (like presented in the WireMock docs - http://wiremock.org/docs/extending-wiremock/). But it sounds like a lot of work for sth that seems not really that necessary. Why do you need to do it like this? On the consumer side you want to test the integration, right? So just hardcode some values in the contract instead of referencing them and just check if you can parse those values.
UPDATE:
If you just need to parametrize the request URL but don't want to reference it in the response you can use regular expressions like here - https://cloud.spring.io/spring-cloud-contract/single/spring-cloud-contract.html#_regular_expressions
UPDATE2:
Like #laffuste has mentioned, starting from RC1 you can reference a concrete path element
I'm in the middle of upgrading a bunch of test harness Groovy(Java) to execute against the Jersey 2.x Client (javax.ws.rs.client.Client), upgrading it from 1.x. I'll likely stumble upon the feature soon but can't see if for the changes I'm making right now. Have been poring through the API looking for an answer to my question.
The new API seems to only permit strict fluent interface verbs e.g.
Response response = invocationBuilder.get();
The old 1.x code allowed a parameter that defines the method type using a string parameter called method:
def response = userServiceContext.target()
.path("/$path")
.method(method, ClientResponse.class)
Annoyingly strict new code displaying a 'put' call (examples):
WebTarget resourceTarget = jerseyClient().target("/$path")
Invocation invocation = resourceTarget.request(MediaType.APPLICATION_ATOM_XML)
.accept(MediaType.APPLICATION_ATOM_XML)
.put(ClientResponse.class, entry)
return invocation.submit()
For convenience sake [asking too much? :) ] could someone point me to an out of the box method that does the same thing in 2.x? I've been digging around the API and I'm finding this an annoying pebble. Bonus points if you explain why that flexibility doesn't exist in the new API (without sass). Apologies in advance to questions like what have you done or why don't you try it and see!??
It looks like you can do something like resourceTarget.request().build(method)... to do what you are looking for. Check out the docs for the build(String method) and build(String method, Entity<?> entity) methods here.
I'm new to scala, but have some experience using the play framework in Java. I've added the SecureSocial authentication library, which defines a SecuredACtion, and it seems to be working correctly. However, I'm having trouble understanding the expected content within the custom action in scala code.
Here's my controllers class. Ideally, "index" would simply redirect the authenticated request to "unprotectedIndex" somehow, but that doesn't seem to be possible. So if not, next best thing is simply to serve the file directly from inside of the secured action, but that's also not working.
What is missing from my code?
object Application extends Controller with securesocial.core.SecureSocial {
// this doesn't compile, but it's a long scala exception that I don't know how to fix.
def index = SecuredAction { implicit request =>
Assets.at("/public", "index.html").apply(request)
}
def unprotectedIndex = Assets.at("/public", "index.html")
}
It seems like it's expecting a SimpleResult but getting a Future[SimpleResult] - this feels like it shouldn't be complicated, but what am I missing?
It seems like you are using play framework 2.2. There were some changes and most methods return Future[SimpleResult] instead of just Result or SimpleResult. You can check if you are able to do like this: def index = SecuredAction.async {...} (but I'm almost sure you can't).
You can use this approach to make it work correctly:
import scala.concurrent.Await
import scala.concurrent.duration._
def index = SecuredAction { implicit request =>
Await.result(Assets.at("/public", "index.html").apply(request), 5 seconds) //you can specify you maximum wait time here
}
EDIT
Even one more thing to simplify:
Await.result(unprotectedIndex(request), 5 seconds)
So you can call your unprotectedIndex from your index Action
So, just by looking at syntax highlighting in my IDE I have been able to get something that seems to compile and work but looks deeply wrong to me.
I changed it to this:
def index = SecuredAction { implicit request =>
Assets.at("/public", "index.html").apply(request).value.get.get
}
Is that the correct way to do this? It looks really weird to me, am I just not familiar with the idioms?
Is there any baked-in way, or established Tapestry pattern, to decouple the name of a page Class from the URL which renders it?
My specific problem is that I have a page class in an English codebase but I want the URLs to be in another language.
For example, the Hello.java page should be accessible from www.example.com/hola rather than the standard www.example.com/hello - though it's fine if both of these URLs work.
Ideally I want something like an annotation to configure a different URL name in-place for each individual page class.
Off the top of my head I could solve this myself with a map of URLs to page class names and a custom RequestFilter to do the mapping on each request - but I don't want to reinvent the wheel if there's a baked-in way to do this or a better pattern that anyone can suggest?
Tynamo's tapestry-routing could help you. It depends on how do you want to generate the links to www.example.com/hola and www.example.com/hello
The #At annotation only allows one route per page, but you can contribute all the routes you want via your AppModule, like this:
#Primary
#Contribute(RouteProvider.class)
public static void addRoutes(OrderedConfiguration<Route> configuration, ComponentClassResolver componentClassResolver) {
String pageName = componentClassResolver.resolvePageClassNameToPageName(Home.class.getName());
String canonicalized = componentClassResolver.canonicalizePageName(pageName);
configuration.add("home1", new Route("/home1", canonicalized));
configuration.add("home2", new Route("/home2", canonicalized));
configuration.add("home3", new Route("/home3", canonicalized));
configuration.add("home4", new Route("/home4", canonicalized));
configuration.add("hola", new Route("/hola", canonicalized)); // the last one is going to be use by default to create links to the page
}
The routes are ordered and by default the last one is going to be used to generate the links.
Currently there is no way to avoid using the default route to generate the links.
Tapestry has a LinkTransformer but I've always found the API lacking since you don't have access to the default behaviour. Igor has written a blog post about the LinkTransformer API here
I've always found it necessary to decorate the ComponentEventLinkEncoder so that I can access the default behaviour and tweak it. See ModeComponentEventLinkEncoder.java and AppModule.java for an example which tweaks the default behaviour and does some string manipulation on the URL.
Thiago has created a url rewriter api here but I've never used it myself. I'm pretty sure his solution is based on decorating the ComponentEventLinkEncoder for outbound URLs and a RequestFilter for inbound URLs.
I'm working on a JSR-303 validation framework for GWT. Some of you may have heard of it even though it is a small project. Here is gwt-validation.
In the old days (v1.0) it used a marker interface for each class and each class had metadata generated separately. This was bad because it was not part of the JSR-303 standard and we moved on to the next idea.
In version 2.0 it scans the classpath at runtime using Reflections. This is great. The downside is that it doesn't seem to be able to work inside of containerized environments or those with special restrictions.
This is probably my fault, look at the following code:
//this little snippet goes through the classpath urls and ommits jars that are on the forbidden list.
//this is intended to remove jars from the classpath that we know are not ones that will contain patterns
Set<URL> classPathUrls = ClasspathHelper.forJavaClassPath();
Set<URL> useableUrls = new HashSet<URL>();
for(URL url : classPathUrls) {
boolean use = true;
for(String jar : this.doNotScanJarsInThisList) {
if(url.toString().contains(jar)) {
use = false;
break;
}
}
if(use) {
useableUrls.add(url);
}
use = false;
}
ConfigurationBuilder builder = new ConfigurationBuilder()
.setUrls(useableUrls)
.setScanners( new TypeAnnotationsScanner(),
new FieldAnnotationsScanner(),
new MethodAnnotationsScanner(),
new SubTypesScanner()
)
.useParallelExecutor()
;
this.reflections = new Reflections(builder);
I'm using the filter to remove jars that I know can't have annotations in them that I'm interested in. As I mention this gives a huge speed boost (especially on large classpaths) but the ClasspathHelper.forJavaClassPath() that I'm basing this on probably isn't the best way to go in container environments. (e.g. Tomcat, JBoss)
Is there a better way or at least a way that will work with a container environment and still let my users filter out classes they don't want?
I've looked, some, into how the Hibernate Validation project (the reference implementation for JSR-303) and they appear to at least be using (at least in part) the Annotations Processing in Java 6. This can't be all of the story because that didn't show up until JDK6 and Hibernate Validator is JDK5 compatible. (See: hibernate documentation)
So, as always, there's more to the story.
I've read these threads, for reference:
About Scannotation which has been pretty much replaced by Reflections.
This one but it uses File and I'm not sure what the implications are of that in things like GAE (Google App Engine) or Tomcat.
Another that goes over a lot of the things I've talked about already.
These threads have only helped so much.
I've also read about the annotation processing framework and I must be missing something. It appears to do what I want but then again it appears to only work at compile time which I know isn't what is done by Hibernate Validator. (Can anyone explain how it does scanning? It works on GAE which means it can't use any of the IO packages.)
Further, would this code work better than what I have above?
Set<URL> classPathUrls = ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader());
Could that correctly get the classloader inside of a Tomcat or JBoss container? It seems scan a smaller set of classes and still finish okay.
So, in any case, can anyone help me get pointed in the right direction? Or am I just stuck with what I've got?
You could take a look at Spring's annotation support.
Spring can scan annotations in files (using asm IIRC), and works in and out of a container.
It may not be easy because it goes through Spring's Resource abstraction, but it should be doable to reuse (or extract) the relevant code.