Calling a static method from Thymeleaf TEXT template - how to bypass the Restricted mode - thymeleaf

Is it possible to call a static method from a Thymeleaf textual template?
Official guide mentions that it should be possible to call a method like this:
<p th:text="${#myapp.translator.Translator#translateToFrench(textVar)}">Some text here...</p>
When I try to use it in my textual template (TemplateResolver's mode is set to TemplateMode.TEXT), I get a this exception:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "#java.lang.System#currentTimeMillis()" (template: "template.txt" - line 1, col 18)
Here is my sample template:
System millis: [(${#java.lang.System#currentTimeMillis()})]
After googling for a while, I also found this form of calling methods:
System millis: [(${T(java.lang.System).currentTimeMillis()})]
which fails with the same error.
What I need to do is somehow allow usage of a custom number formatter class from a template (functionality of the #numbers utility object is not rich enough for my case).
I can call methods on a non-static class by providing it as a context variable like this:
Some value: [(${formatter.format(someValue)})]
but it would be easier for me to use a static class without a need to explicitly adding it to each template's context.
BTW, I do not use Spring, just pure Thymeleaf.
Update
I should've spend more time to analyze the stack trace of the Thymeleaf exception I got.
It turns out, that the root cause of this behavior was the org.thymeleaf.exceptions.TemplateProcessingException: Instantiation of new objects and access to static classes is forbidden in this context exception, which is results from this change: https://github.com/thymeleaf/thymeleaf/issues/809
Downgrading to Thymeleaf 3.0.11 "fixes" it.
Now I'm looking for a solution to bypass this new Resctricted mode on the latest Thymeleaf (3.0.12 for the moment). I'm sure it's safe in my case, because I'm the only author of both code and templates.

An alternative would be to use the th:with attribute. It's a little more verbose, but still should allow you the same flexibility. (This works for me on 3.0.12.RELEASE.)
[# th:with="time=${#java.lang.System#currentTimeMillis()}"]System millis: [[${time}]][/]

https://github.com/thymeleaf/thymeleaf/issues/816#issuecomment-826401631 has extensive info on why this was done and possible workarounds. In your case, it will be best to add a model attribute in your controller and use that instead of calling the static method in the template.
#Controller
public class MyController {
public String myControllerMethod(Model model) {
model.addAttribute("time", System.currentTimeMillis());
return "name-of-the-thymeleaf-template";
}
}
and update your template to use:
System millis: [(${time})]

Related

How can I add a named property that is not part of the message template?

In some cases, I would like to add contextual information to a message (for instance currently authenticated user), without having to include it in the message template.
I would like to accomplish this :
logger.Information("Doing stuff {Foo} with the thing {Bar}. {User}", foo, bar, user)
but without the {User} in the template.
I already know about LogContext but that seems overkill when adding contextual information to just one event.
I also know I can use the low-level API logger.Write(LogEvent evnt) to actually control which properties are included, but that seems like a bit too much code for what I am trying to accomplish.
I'm pretty sure there is a short and elegant way that is super obvious, but I haven't found it :)
UPDATE :
I found out only afterwards that this question is more or less similar : Add custom properties to Serilog
I could figure it out on my own!
You can use the fluent method .ForContext(propertyName, propertyValue) on a single call to one of the .LogXXX() methods.
For instance :
logger.ForContext("User", user)
.Information("Doing stuff {Foo} with the thing {Bar}", foo, bar)
The property added to the event only apply to the event, and they are no longer present on the next call to the logger.LogXXX() method
UPDATE
The article by Nicholas Blumhardt explains it quite well : Context and correlation – structured logging concepts in .NET (5)
If you're using the generic Microsoft ILogger you can use BeginScope;
using (_logger.BeginScope(new Dictionary<string, object> { { "LogEventType", logEventType }, { "UserName", userName } }))
{
_logger.LogInformation(message, args);
}
This is discussed here; https://blog.rsuter.com/logging-with-ilogger-recommendations-and-best-practices/

binding request parameters to action arguments

In Grails you can declare a controller action like this:
def create(Integer foo, Integer bar) {
}
And if your HTTP request has parameters named foo and bar with values that can be converted to an Integer, the parameters will be assigned these values. I'm wondering how Grails can do this, because my understanding is that at the JVM bytecode level, a method's formal parameter names are not available. Is this witchcraft or am I misunderstanding something?
Basically what happens is that there's an AST transform that adds a new method with no args and the same name. This new method has logic in it to do the data binding based on the declared types of your "real" method, and then call your method. That's why the types are required (otherwise there's no way to do a conversion) and why you cannot have method overloads.
The inability to have overloaded methods is easy to work around though. Say you wanted an action
def foo(String bar)
and another
def foo(String bar, Integer wahoo)
In this scenario just keep the 2nd method and check to see if wahoo is null.
It's also important to use object parameter types and not primitives. If you use int/long/boolean/etc. and there is no provided parameter, you would get a NPE (since zero is not an acceptable conversion from null for numbers, and either is false for booleans).
You can get a decent sense for what's going on if you decompile the class using JD-GUI or another decompiler.
The fact that Grails controllers are Groovy classes helps quite a lot. Looking through the source code for controllers you can see where it makes heavy use of AST transformations, in particular the MethodNode. So, before it becomes bytecode the "witchcraft" is done. :)

Adding parameter to AuthorizeAttribute constructor causes failure in MvcSiteMapProvider?

I've been using MvcSiteMapProvider based on authorize attributes and it was all right until we introduced a new class derived from AuthorizeAttribute. Main difference is in its constructor signature:
public MyAuthorizeAttribute(param RoleCode[] roles) {
Roles = string.join(",", roles.Select(r => r.ToString());
}
And... MvcSiteMapProvider shown unexpected result: only actions marked by MyAuthorizeAttribute became invisible. I've checked that by disabling this constructor - everything went as it had been before adding a parameter to the constructor. Also - it's not params specific - any parameter (event int) leads to such behaviour.
AS I understood from MvcSiteMapProvider sources, it emits some code to emulate authorize attributes - but looks like it's impossible to save assembly generated by external code. I know that there is a workaround - use some kind of enumerable property, but have you got any suggestions how to make it work with constructor parameters? Do you know why MvcSiteMapProvider behaves like that?
So, after spending some time in debugging, I realized the answer: dynamic proxies.
The problem is that during request execution inside MVC framework there is no easy way to find out how a class derived from AuthorizeAttribute performs its work. In case of access check failure some could throw exception, some - return 401 status code, some redirect to login page at once, and so on.
But MvcSiteMapProvides does that! It uses the following workaround:
if class is AuthorizeAttribute:
create an instance of InternalAuthorize class which is fairly simple.
copy all properties there and
invoke AuthorizeCore method which returns boolean value.
else
generate a proxy class derived from a type of attribute,
create instance, /// << here we get an exception
copy all properties there and
invoke AuthorizeCore method which returns boolean value.
As it is clear, that's not an easy task to make a proxy, which is aware of your constructor parameters. Exception about default constructor absence is thrown, of course, but it is then consumed by empty catch clause. That is really sad - at least a single debug trace would have saved me a couple of hours.
So the answer at last:
Obviously you should use parameterless attribute constructor (why oh why that's not mentioned anywhere?)
Make custom acl provider: implement IAclModule interface and unleash your knowledge about your own authorize attributes within it.

How do I implement error-handling in Grails?

I am just starting out with Grails, obviously. I've created my domain class and controller, added my own logic to the controller, and everything is working properly -- as long as nothing goes wrong.
My custom controller action looks like this:
def create = {
try
{
// Get the parameters.
def uid=params["uid"]
def pwd=params["pwd"]
if (!uid || !pwd)
{
throw new Exception('User ID and password are required')
}
/* other code */
}
catch (Exception ex)
{
println ex.getMessage()
}
}
My code (/* other code */) is working fine. When the exception is thrown, however, the error message is printed to the console and the browser throws a 404 error. Obviously, this isn't the way to go.
What's the correct way to do this?
TIA,
John
Based on the code snippet you provided, I guess what you really want is validation of some sort of user input (probably a form). If this is the case, throwing exceptions definitely isn't the way to go. You should only throw an exception if something exceptional (something unexpected, that usually shouldn't happen during normal operation) happens - by the way, this also holds for other programming languages.
Grails provides very good support for validating user inputs. Depending on the context, you should either define constraints in your domain classes, or use command objects and define constraints there (if the fields to be validated are not backed directly by a domain class). This way Grails validates the user input automatically against your constraints (there are many different kinds, such as size, blank/non-blank, or even RegExp constraints) and stores the errors and the corresponding messages in the domain class. You can then easily display the appropriate localized error messages in your form (view). It's good practice to display the errors right next to the input field they refer to.
Have a look at the Reference Documentation - especially chapter 7 (validation).
The 404 you are getting is probably not due to the (caught) exception, but rather because you don't have a view called create.gsp or a render/redirect call in your action.
I hope this answers your question or at least points you in the right direction. Good luck!
As Daniel says, use constraints in your domain class instead and use the validate() method in your controller instead of throwing exceptions.
If validate() returns false, render the form again with an error message.
In your BootStrap.groovy file you can do this set up catch-all handlers for different Java Exceptions. Here is an article about it.

MVC Best Practices | Do you build your links into the Url Helper?

Just read a post about MVC best practices. Couple parts of the post described building helper methods to link to actions on the controllers. Here's a clip:
1) Create Extension methods of UrlHelper to generate your url from
Route
Avoid passing the controller, action
or route name as string, create
extension methods of UrlHelper which
encapsulates it, for example:
public static class UrlHelperExtension
{
public static string Home(this UrlHelper helper)
{
return helper.Content("~/");
}
public static string SignUp(this UrlHelper helper)
{
return helper.RouteUrl("Signup");
}
}
I can see how this would shorten links used in views... but I don't see how this is a "best practice". Perhaps I'm simply overlooking something. Should I be doing this to build my links? Are there benefits to this I'm just not seeing?
He even goes on to say that stylesheets, images, and javascript helpers should be made...
I probably wouldn't do this unless the route is referenced in multiple places. I can see the value in doing this, and I have implemented HtmlHelper extensions for adding style sheets and javascript includes to add the ability to use "versioned" links, but my common links are included as ActionLinks in a UserControl (menu) and for most other things I use either ActionLink or BeginForm/AjaxForm to reference the action. In some respects it feels like creating new methods for all but the most commonly reused links is adding complexity for very little value -- the kind of value that you would get from some simple manual testing of your UI, which you'd have to do anyway.
If you make a mistake when writing a URL as a string, it won't be caught until runtime. This way, attempting to refer to a route that hasn't been created as an extension method will create errors at compile-time, which you can quickly correct (even earlier, if you use Visual Studio). If you discover a mistake in the way you formulated a route, you only have to fix it in one place.
Although, instead of cluttering your UrlHelpers with extension methods, it might be better to have a static class called something like CommonUrls that holds static readonly properties (or static methods, if you prefer).
EDIT: I just realized that you would need to pass an instance of your UrlHelper to the CommonUrls class. Silly me. In that case, extension methods probably are the right tool for the job.
That's one person's opinion of what a best practice is. There are a few cases where it might be nice. If you have people working with the views while the URL structure is still being worked out you won't have to update the views once the URLs are finalized.
Should anyone else happen to stumble on this old post, I would suggest using the T4MVC templates by David Ebbo: See his latest blog post here.
I don't see this as a best practice. For one thing you're going down the path of burying structural specifics down in a bunch of extension methods. (Although you could use resources for the paths, it would mean high-friction changes.)
Further, at what point do you stop? For a site of any complexity you're going to need a lot of these helpers.
I've used a somewhat similar approach when referencing stylesheets, javascript, favicons, etc. although I use HtmlHelper rather the UrlHelper extensions as conceptually I think they're more suited to the task.
Further, because such things are typically added to a master page only, there's no issue with simply passing the complete path into the helper and having it construct an entire tag - rather than just resolve a URI.
I'm using this approch.
It's very useful when your application sitemap is subject to changes.
And yes, you need a lot of those (I my extension class count 1800 lines, with comments)
Main difference, in my case, I build the URL using a strongly-typed builder. It looks like this :
/// <summary>
/// To campaign 'transfer credits' page
/// </summary>
public static string ToCampaignTransferCredits(this UrlHelper helper, int? idCampaignSource)
{
return To<CampaignController>(helper, c => c.Transfer(idCampaignSource));
}
I think this is a very good practice (IMHO) for some reasons :
you have a clear separation between navigation available page/actions and your controllers. I recently had to move methods from one controller to another, and it worked without pain/refactoring/testing.
it's compiled so if you change a controller's method signature you are awared of the changes to do (and you only have 1 or 2 changes, no need to check the whole application)
you can use inheritance and generics on your controllers like a OOP geek, cascade the calls and whatever you find powerful, this approach will hide all the underlying complexity, leaving simples call in the views.

Resources