You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Steve Eynon <st...@alienfactory.co.uk> on 2012/08/29 12:27:59 UTC
How to return HTTP 404 for in-exact URL requests
A topic that crops up time and time again is that of the elusive HTTP
404 in T5 apps.
When running a public website, for SEO reasons, it is desirable for
in-exact urls to return a HTTP 404 rather than returning a 'best fit'
page.For the same reasons, it is undesirable for malformed urls to
return an HTTP 500. So in T5.3.4, I finally got round to converting
all those URL requests to HTTP 404s.
The approach taken is to generate a 'MangledUrlException' at poignant
points and have an ExceptionHandler catch this specific exception to
return a HTTP 404.The code changes I use to throw a
'MangledUrlException' are outlined below:
My method of catching and identifying the MangledUrlException (as it's
often wrapped deep inside a T5 exception) may not be suitable for all,
so I've left that part out.
Use Case 1 : Illegal Url "http://localhost/spa%20ce"
This usually gives a java.lang.IllegalArgumentException:
- Input string 'spa ce' is not valid; the character ' ' at position 4
is not valid.
To your module add:
@Advise(serviceInterface=ContextPathEncoder.class) @Traditional
public static void adviseContextPathEncoder(MethodAdviceReceiver
receiver, @Autobuild AdviseContextPathEncoder advice) throws
SecurityException, NoSuchMethodException {
Method method = ContextPathEncoder.class.getMethod("decodePath",
String.class);
receiver.adviseMethod(method, advice);
}
public class AdviseContextPathEncoder implements MethodAdvice {
@Override
public void advise(MethodInvocation invocation) {
try {
invocation.proceed();
} catch (IllegalArgumentException e) {
throw new MangledUrlException();
}
}
}
Use Case 2 : Illegal Url "http://localhost/index.wotever"
This usually gives an org.apache.tapestry5.ioc.util.UnknownValueException
- Component Index does not contain embedded component 'wotever'.
@Advise(serviceInterface=ComponentEventRequestHandler.class)
public static void
adviseComponentEventRequestHandler(MethodAdviceReceiver receiver,
@Autobuild AdviseComponentEventRequestHandler advice) throws
SecurityException, NoSuchMethodException {
Method method =
ComponentEventRequestHandler.class.getMethod("handle",
ComponentEventRequestParameters.class);
receiver.adviseMethod(method, advice);
}
public class AdviseComponentEventRequestHandler implements MethodAdvice {
private final String className;
private final String methodName;
public AdviseComponentEventRequestHandler() throws
SecurityException, NoSuchMethodException {
// set these early so we're notified of any API changes
// PageImpl isn't a service, so we can't advise it directly!
className = PageImpl.class.getName();
methodName =
PageImpl.class.getMethod("getComponentElementByNestedId",
String.class).getName();
}
@Override
public void advise(MethodInvocation invocation) {
try {
invocation.proceed();
} catch (UnknownValueException e) {
if (componentIdIsMangled(e)) {
ComponentEventRequestParameters params =
(ComponentEventRequestParameters) invocation.getParameter(0);
throw new MangledUrlException(params.getActivePageName(),
MangledUrlMessages.componentNotFound(params.getNestedComponentId()),
e);
}
}
}
private boolean componentIdIsMangled(UnknownValueException e) {
for (StackTraceElement stackElement : e.getStackTrace())
if (stackElement.getClassName().equals(className) &&
stackElement.getMethodName().equals(methodName))
return true;
return false;
}
}
Use Case 3 : Unwanted context "http://localhost/index/unwanted"
This usually returns the index page.
@Contribute(ComponentClassTransformWorker2.class)
@Primary
public static void
provideTransformWorkers(OrderedConfiguration<ComponentClassTransformWorker2>
configuration) {
configuration.addInstance("ContextNotRequiredWorker",
NotRequiredWorker.class, "after:*");
}
/**
* It's important that that this is added "after:*" as we need to
ensure no-one else has added onActivate() handlers.
*/
public class NotRequiredWorker implements ComponentClassTransformWorker2 {
@Override
public void transform(PlasticClass plasticClass,
TransformationSupport support, MutableComponentModel model) {
if (!model.isPage())
return;
// FUTURE: this does not identify mixins which implement onActivate()
if (model.handlesEvent(EventConstants.ACTIVATE))
return;
support.addEventHandler(EventConstants.ACTIVATE, 0,
"NotRequiredWorker activate event handler",
new ComponentEventHandler() {
@Override
public void handleEvent(Component instance, ComponentEvent event) {
if (event.getContext().length > 0) {
String pageName = instance.getComponentResources().getPageName();
throw new MangledUrlException(pageName,
MangledUrlMessages.contextNotWanted(event.getEventContext().toStrings()));
}
}
});
}
}
--
Steve Eynon
-------------------------------
"If at first you don't succeed,
so much for skydiving!"
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: How to return HTTP 404 for in-exact URL requests
Posted by Steve Eynon <st...@alienfactory.co.uk>.
If T5 could throw more specific exceptions, as oppose the generic ones
that it does, then it'd be a simple exception handling matter for the
user to decide what to do. (As mentioned above.)
I rose a JIRA about this last year:
Throw bespoke exceptions so they may be more easily identified by Error Handlers
https://issues.apache.org/jira/browse/TAP5-1733
Steve.
On 29 August 2012 19:20, Lance Java <la...@googlemail.com> wrote:
> It sounds like you are fixing something that really should be handled by
> tapestry. I agree that a 404 is much better than a 500 in these cases and I
> think it should be the default behavior.
>
>
>
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-return-HTTP-404-for-in-exact-URL-requests-tp5715875p5715876.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
How to return HTTP 404 for in-exact URL requests
Posted by Lance Java <la...@googlemail.com>.
It sounds like you are fixing something that really should be handled by
tapestry. I agree that a 404 is much better than a 500 in these cases and I
think it should be the default behavior.
--
View this message in context: http://tapestry.1045711.n5.nabble.com/How-to-return-HTTP-404-for-in-exact-URL-requests-tp5715875p5715876.html
Sent from the Tapestry - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org