The Header section (Apache Tiles Attribute) is shared by several views. It has a form that expects an Object when the page is loaded and complains if the Object is missing. At the moment I am placing the Object in a Model and passing it to the View using the Controller every time I create a view that inherits this layout.
This approach seems rather tedious as i have repeated lines all over the Controller. I'd like to be able to add it once and be done with.
I am not too familiar with Apache Tiles there maybe a simple solution that I am not aware of.
Looking for some helpful tips.
Thanks
You can use the HandlerInterceptorAdapter class and the postHandle method to achieve something like that. By cons, you will need to define a rule that will help you to know when the object need to be add to the model, it can be the path or something in the url, it depends on how your template is organized. Here an example of an interceptor that is doing something like that.
The interceptor defenition :
<mvc:interceptors>
<bean class="your.package.HeaderModelInterceptor"/>
</mvc:interceptors>
The interceptor class :
public class HeaderModelInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// Check if you need to add the object
if (Your rule) {
modelAndView.addObject("headerObject", headerObject);
}
super.postHandle(request, response, handler, modelAndView);
}
}
You have a couple of options to do this. Off the top of my head you could.
Use Tiles view preparers, simple example here
Use a mechanism like Spring interceptors or AOP to automatically add your object to the Model instead of repeating the code everywhere
It really depends on the nature of the object you're adding and how much context it needs.
Related
I am working in a RESTful application developed in Apache CXF and I would like to introduce hypermedia functionality to it.
Most of our jaxrs:serviceBeans follow this template:
#GET
#Path("/{exampleId}")
public ExampleJSON get(#PathParam("exampleId") Integer exampleId) {
ExampleJSON example;
// Load data from repository here...
// Add link to self.
String href = javax.ws.rs.core.Link.fromResource(ExampleService.class).build().getUri().toString();
// HypermediaLink is a custom object to hold a "href" and "rel" strings
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + example.getId());
linkToSelf.setRel("self");
// Inherited method, just adds a HypermediaLink to a collection in the parent class
example.addHypermediaLink(linkToSelf);
// Return JSON compatible object, JACKSON will serialize it nicely.
return example;
}
This is the basic concept. Keep in mind that I simplified this code for explanation purposes; so, it can be easily understood.
This code works fine; but I am wondering if there is a better way to do this with Apache CXF. I have some ideas for how to enhancing it; however, it will require some custom annotations.
I see some examples using Jersey, but I would like to stick with Apache CXF.
Any help would be appreciated.
Thanks
I would leverage some features of JAX-RS and / or Jackson to implement the link adding under the hood at the serialization level. So you wouldn't need to have a specific field for the link within the bean itself.
You could implement a custom MessageBodyWriter to generate a different JSON payload (for example) for your POJOs than the default. So you could dynamically add the link.
See this answer for more details: How to write an XML MessageBodyWriter provider with jersey.
If you use Jackson for the serialization, you could implement a custom serializer. Note that this is generic and will work for all supported format of Jackson.
Below is a sample code:
public class LinkBeanSerializer extends JsonSerializer<SomeBean> {
#Override
public void serialize(SomeBean bean, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
// Fields
jgen.writeNumberField("id", bean.getId());
// Things could be generic using reflection
// Link
String href = javax.ws.rs.core.Link.fromResource(SomeBean.class).build().getUri().toString();
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + bean.getId());
linkToSelf.setRel("self");
jgen.writeObjectField("hypermediaLink", linkToSelf);
jgen.writeEndObject();
}
}
Note that we could make this serializer more generic I think (something like extends JsonSerializer<Object>)
See this answer for more details: Processing JSON response using JAX-RS (how to register the custom serializer within JAX-RS, ...).
Perhaps implementing a WriterInterceptor could solve your problem but there is impact on the beans since you need to have field hypermediaLink. The interceptor could be responsible of filling the field.
See this answer for more details: Jersey Update Entity Property MessageBodyWriter.
IMO the more convenient solution is the second one. It's transparent and support all the formats supported by Jackson.
Hope it helps you,
Thierry
I want to save a list of entity objects in RequestFactory. Most of the time, i can find
RequestContext with Save(EntityProxy) alone and not with Save(List of EntitProxy).
Is it possible to do in GWT ?
In your RequestContext, add a method like
Request<Void> save(List<MyEntityProxy> proxies);
and have that map to a method like
public void save(List<MyEntity> entities)...
in your service class.
This may need to be static, depending on how you are using locators, and what kind of Request you are using. If this isn't working, can you post the full RequestContext (including annotations) and the error that occurs? It might give a hint as to why it isn't working correctly.
I've been trying to wrap my head around the topics posted at this similar question:
Is it possible to use Dependency Injection/IoC on an ASP.NET MVC FilterAttribute?
However, I'm just not getting anywhere. Not to mention, all the solutions appear to have dependencies on other libraries which I'm not able to use (MvcContrib, Unity).
Can anyone toss together some code to explain how to make this property injection work? Or if there is another way to make this happen?
Thanks much!
Relevant code 1: Controller
namespace TxRP.Controllers
{
[GetMasterPageData]
public class BaseController : Controller
{
}
}
Relevant code 2: ActionFilter
public class GetMasterPageData : ActionFilterAttribute
{
private IEmployee emp; //<--Need to inject!
private ICache cache; //<--Need to inject!
/// <summary>
/// ActionFilter attribute which inserts the user name, access level and any error/warning messages to the MasterPage
/// Session variables which are consumed primarily by the LogOnUserControl.
/// The MasterPage will display any warning or error messages.
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Code
}
It's not possible to use DI with attributes because they are statically compiled into your classes, so nothing can ever be injected. Some people may tell you that you can use a sort of static factory to get your dependencies, but that's not Dependency Injection - that would be Service Location - which is an anti-pattern.
However, it's possible to combine DI with action filters if you abandon the idea of attributes, but not particularly easy. You'll need to create a custom IActionInvoker, although the easiest way to do that is to derive from ControllerActionInvoker and override its GetFilters method. Here's a blog post that explains how to do that for error handling - you should be able to extrapolate from that.
When you get tired of doing that I'd advice you to switch to composing cross-cutting concerns out of Decorators and other design patterns. In that way you can implement your cross-cutting concerns independently of constraining technology.
HtmlHelpers are really useful, also i was using AjaxHelpers untill i wanted to do something they can't... so now i'm prefering jquery+javascript, but i don't like to write in javascript (mayby because i never know it as good as i wanted) and to make life easier i wanted to implement something like JQueryHelper, but right now i don't know how
I wanted to use inside of "Helper" resolved URL's, because most methods would just pass data to controllers etc... and update some parts of UI, so i'd like to create something like AjaxHelper, but based on JQuery, not MSScripts.
What should I include in such class? how can i get context, url's and generate proper javascript code which can by dynamicly injected into
ex.
<div onclick=JQuery.Action("<ActionName>", "<Controller>", new { param1, param2}, <Id to Update>)> My Div</div>
How is it implemented in HtmlHelper or AjaxHelper?
Edit:
I've tried few simple implementation, but i think I'm lack of knowledge and don't know how to implement class with extensions exacly.
I've ClassA(class) and ClassAExt(extensions):
I've something like that:
static public class ClassAExt{
public static MvcHtmlString Method(this ClassA classA) {
}
}
But in View(), when I'm using ClassAExt.Method() i have to pass also instance of ClassA (in helpers Ajax and Html this argument is grey (optional? not needed?), how to get such effect).
I am not sure if I understand your question correctly.
The HtmlHelper also get instantiated (i.e. new HtmlHelper()) during the course of page rendering and user control rendering. Ajax and URL helpers also get instantiated and this is what give one access to the various variables such HttpContext etc.
So in order for you to use your helper class related to ClassA you too will need to instantiate it. I think then the question leads to how do I do this? You will probably need to extend the ViewPage, ViewUserControl and ViewMasterPage classes.
Its non obvious because its so obvious. Basically, you extend html helper's extension:
public static HtmlString Foo(this HtmlHelper helper, string param)
{
//do whatever
}
You can get at request context, etc, from HtmlHelper.
Way I see it, you problem is that you don't understand extension methods.
if you have
static public class ClassAExt{
public static MvcHtmlString Method(this ClassA classA) {
}
}
you use it in view like this:
<%: ClassAInstance.Method() %>
to do that, you have to add <add namespace="NamespaceOfClassA" /> to you web.config's pages/namespaces section.
This way, you can extend the HtmlHelper class to do whatever you need, so there is really nothing it can't do. If you want it to do something it can't by default, just write an extension method. Also download MVC Futures assembly, there's a dll Microsoft.Web.Mvc that contains (among other things) a lot of useful extension methods for HtmlHelper.
If you want to know how they implemented HtmlHelper or AjaxHelper you can check out MVC source code.
Link to download both MVC Futures and MVC source code: http://aspnet.codeplex.com/releases/view/41742
I want to handle different types of docs the same way in my application
Therefore:
I have a generic interface like this.
public interface IDocHandler<T>where T: class
{
T Document { get;set;}
void Load(T doc);
void Load(string PathToDoc);
void Execute();
void Execute(T doc);
}
And for different types of documents I implement this interface.
for example:
public class FinanceDocumentProcessor:IDocumentHandler<ReportDocument>
{}
public class MarketingDocumentProcessor:IDocumentHandler<MediaDocument>
{}
Then I can do of course something like this:
IDocumentHandler<ReportDocument> docProc= new FinanceDocumentProcessor();
It would be interessting to know how I could inject T at runtime to make the line above loosly coupled...
IDocumentHandler<ReportDocument> docProc = container.resolve("FinanceDocumentProcessor());
but I want to decide per Configuration wether I want to have my FinanceDomcumentProcessor or my MarketingDocumentProcessor... therefore I would have to inject T on the left site, too ...
Since I have to use c# 2.0 I can not use the magic word "var" which would help a lot in this case... but how can I design this to be open and flexible...
Sorry for the misunderstanding and thanks for all the comments but I have another example for my challenge (maybe I am using the wrong design for that) ...
But I give it a try: Same situation but different Explanation
Example Image I have:
ReportingService, Crystal, ListAndLabel
Three different Reporting Document types. I have a generic Handler IReportHandler<T> (would be the same as above) this Handler provides all the functionality for handling a report Document.
for Example
ChrystalReportHandler:IReportHandler<CrystalReportDocument>
Now I want to use a Framework like Unity (or some else framework) for dependency injection to decide via configuration whether I want to use Crystal, Reportingservices or List and Label.
When I specify my mapping I can inject my ChrystalReportHandler but how can I inject T on the left side or in better word The Type of ReportDocument.
IReportHandler<T (this needs also to be injected)> = IOContainer.Resolve(MyMappedType here)
my Problem is the left Site of course because it is coupled to the type but I have my mapping ... would it be possible to generate a object based on Mapping and assign the mapped type ? or basically inject T on the left side, too?
Or is this approach not suitable for this situation.
I think that with your current design, you are creating a "dependency" between IDocumentHandler and a specific Document (ReportDocument or MediaDocument) and so if you want to use IDocumentHandler<ReportDocument or MediaDocument> directly in your code you must assume that your container will give you just that. The container shouldn't be responsible for resolving the document type in this case.
Would you consider changing your design like this?
public interface IDocumentHandler
{
IDocument Document { get; set; }
void Load(IDocument doc);
void Load(string PathToDoc);
void Execute();
void Execute(IDocument doc);
}
public class IDocument { }
public class ReportDocument : IDocument { }
public class MediaDocument : IDocument { }
public class FinanceDocumentProcessor : IDocumentHandler { }
public class MarketingDocumentProcessor : IDocumentHandler { }
If I understand you correctly, you have two options.
if you have interface IDocHandler and multiple classes implementing it, you have to register each type explicitly, like this:
container.AddComponent>(typeof(FooHandler));
if you have one class DocHandler you can register with component using open generic type
container.AddComponent(typeof(IDocHandler<>), typeof(DocHandler<>));
then each time you resolve IDocHandler you will get an instance of DocHandler and when you resolve IDocHandler you'll get DocHandler
hope that helps
You need to use a non-generic interface on the left side.
Try:
public interface IDocumentHandler { }
public interface IDocumentHandler<T> : IDocumentHandler { }
This will create two interfaces. Put everything common, non-T-specific into the base interface, and everything else in the generic one.
Since the code that you want to resolve an object into, that you don't know the type of processor for, you couldn't call any of the T-specific code there anyway, so you wouldn't lose anything by using the non-generic interface.
Edit: I notice my answer has been downvoted. It would be nice if people downvoting things would leave a comment why they did so. I don't care about the reputation point, that's just minor noise at this point, but if there is something seriously wrong with the answer, then I'd like to know so that I can either delete the answer (if it's way off target) or correct it.
Now in this case I suspect that either the original questionee has downvoted it, and thus either haven't posted enough information, so that he's actually asking about something other than what he's asked about, or he didn't quite understand my answer, which is understandable since it was a bit short, or that someone who didn't understand it downvoted it, again for the same reason.
Now, to elaborate.
You can't inject anything "on the left side". That's not possible. That code have to compile, be correct, and be 100% "there" at compile-time. You can't say "we'll tell you what T is at runtime" for that part. It just isn't possible.
So the only thing you're left with is to remove the T altogether. Make the code that uses the dependency not depend on T, at all. Or, at the very least, use reflection to discover what T is and do things based on that knowledge.
That's all you can do. You can't make the code on the left side change itself depending on what you return from a method on the right side.
It isn't possible.
Hence my answer.