RequestMapping Packages in Spring - spring

So I'm currently developing a platform for my work using Spring MVC 3.2, with an XML configuration, and what I'm looking for is some syntactic sugar.
Basically we have numerous controllers, and since I've been the one who organized all the packages, I packed them in the same method I've gotten used to in Angular JS (i.e related concepts with related).
So now I have a package structure of:
com.company.general
com.company.general.security
com.company.general.accounts
com.company.reports
com.company.reports.someReport
com.company.reports.anotherReport
Now the big issue I'm personally having (it's more I'm looking for an easy way to do this) is trying set a standard path for a specific package.
After reading the above I realize it is not so clear, so I'll try and clarify.
Right now, each of my controllers under the reports package, have:
#Controller
#RequestMapping("/reports/reportName")
Now the only thing that changes in that chunk of code is the reportName for different controllers.
I'm unsure how to, if it is at all possible, to have it so I can specify, all controllers under package com.company.reports has a default "/reports/" path, and then when I specify the #RequestMapping in the controller it simply appends to this.
I thought this would be something doable through when I setup the since it seemed logical with it doing the assignment (or what I believe the assignment of paths) but to no avail.
Any help would be much appreciated, many thanks

You can, maybe, try with an abstract class:
#RequestMapping(value = "/reports")
public abstract class AbstractReportController {
...
}
public class MyReport extends AbstractReportController {
#RequestMapping(value = "/myReportName")
public String aMethod(Model model) {
...
}
}
public class AnotherReport extends AbstractReportController {
#RequestMapping(value = "/anotherReportName")
public String aMethod(Model model) {
...
}
}
This work.

Related

Spring custom annotation for this behavior

I have code like this.
#org.springframework.stereotype.Component("studentInfo")
#org.springframework.context.annotation.Profile("studentInfo")
public class CustomStudentInfo{
As you can see i have the component name and the same profile i mean i just want to set this class as a bean only when the profile is set and fact this is working but is kind annoying to type this on 2 lines my question is can i have this on a custom annotation i mean a annotation that help me just to write.
#CustomSpringAnnotation("studentInfo")
public class CustomStudentInfo{
Thanks and sorry if the question is plain.
You can "incorporate" the spring annotations into a custom one like (source/proof: SpringBootApplicaiton source code):
package my.package.annotations;
#org.springframework.stereotype.Component("studentInfo") // needs "constant expression" here
#org.springframework.context.annotation.Profile("studentInfo") // .. and here!
public #interface MyCustomSpringAnnotation { ...
// but here you have a problem,
// since you cannot pass (at least not to the above annotations,
// ... but maybe dynamically *hack* into the spring context):
String value() default ""; //?
}
...then you could use it like:
#MyCustomSpringAnnotation
public class CustomStudentInfo { // ...
but with the fixed "studentInfo" it is no improvement (but the contrary).
The probably "most spring-like" and best solution (no stress with "too many annotations") is: To consume "studentInfo" from a "visible" (static) final variable (probably best in the affected class):
#org.springframework.stereotype.Component(CustomStudentInfo.PROFILE_NAME)
#org.springframework.context.annotation.Profile(CustomStudentInfo.PROFILE_NAME)
public class CustomStudentInfo {
public static final String PROFILE_NAME = "studentInfo";
// ...

Repository pattern in MVC: controller code explanation

What is the purpose of SudentRepository in this example? Why do I need one?
public class StudentController : Controller
{
private IStudentRepository _repository;
public StudentController() : this(new StudentRepository())
{
}
public StudentController(IStudentRepository repository)
{
_repository = repository;
}
I updated to actually include a specific question that I think you're getting at. The purpose of StudentRepository is to encapsulate interactions with persisted data. The Controller need not know if its stored in a db, flat file, in memory, etc.
The reason you're injecting it in via an interface is because you may eventually have multiple implementations of that repository, and the interface is just a contract to ensure basic functionality across all implementations. This is called constructor injection (a type of dependency injection) in case you want to learn more.

ZK & Spring - Safe to use Executions.getCurrent() in Spring Bean?

I want to create a utility Bean for common URL parsing in my ZK Composers. However, I want to make sure it is safe to use things like Executions.getCurrent() in a Spring managed Bean. I'm pretty sure it is as Executions.getCurrent() is static to begin with.
Here's what I'm thinking of doing..
#Component
public MyUrlBean {
// TODO I will, of course, program to an interface here =)
private static final String MY_OBJECT_URL_PARAMETER = "my_obj";
public MyObject getMyObjectFromURL() {
Execution ex = Executions.getCurrent();
String value = ex.getParameter(MY_OBJECT_URL_PARAMETER)
// ... db fetch and the like
}
}
..used like so..
#VariableResolver(DelegatingVariableResolver.class)
public MyComposer extends SelectorComposer<Window> {
#WireVariable
public MyUrlBean myUrlBean;
#Override
public void doAfterCompose(Window component) {
MyObject myObject = myUrlBean.getMyObjectFromURL();
// ...
}
}
So, doing things this way, should everything work fine or should I anticipate problems with user sessions clashing or the like?
Spring beans are NOT static singletons, correct? Instead they are instance classes that are autowired to save computation time of actually newing up objects, correct? If that is the case then there definitely won't be clashes between users like this.
Anyway, as I mentioned, Executions.getCurrent() is static. Hmm, how does that work with multiple users accessing a webapp?
Yes, it's safe.
I don't have much official sources to link here, but for what it's worth, my previous team has been using this in almost every page (to get a user context) of an app serving over 3000 users in production with no recorded problem in two years.

Why does Spring allow controller annotated request mappings on private methods?

Just came accross this today in a Spring MVC cotnroller class,
#RequestMapping(value = { "/foo/*" }, method = { RequestMethod.GET})
private String doThing(final WebRequest request) {
...
return "jsp";
}
This is making it a bit harder to write a test, I'll probably change it to public but what's the point of allowing mappings on private methods?
Java does not provide a mechanism for limiting the target of annotations based on access modifier.
As #smp7d stated, Java does not limit the target of annotations based on access modifiers, but syntactically speaking, #RequestMapping should not work on private methods. Also we cannot limit this, since it would break the backward compatibility. So, you can either go for defining your methods as public or you can create your own custom implementation.
Take a look at this: Spring's #RequestMapping annotation works on private methods

Property Injection without attributes using Ninject in an abstract base controller in MVC3

I have the following code:
public abstract class BaseController : Controller
{
public IUserService UserService { get; set; }
}
All my controllers inherit from this base controller. I started out by configuring it in Ninject using the following code:
kernel.Bind<BaseController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This did not work. I assume it is because of the fact that the BaseController is an abstract class (please confirm my assumption). So I moved on to modify the configuration to:
kernel.Bind<HomeController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This does work. The minor downside is that I now have to configure every controller the same way.
Since I also have DependencyResolver setup in my ASP.NET MVC 3 project I could also remove the above Ninject configuration and modify my base controller to look like:
public IUserService UserService
{
get
{
return DependencyResolver.Current.GetService<IUserService>();
}
}
Is there any benefit to using the fluent configuration as opposed to using the DependencyResolver approach? Is one better than the other? Which approach would be considered a better practice?
It is worth mentioning that I did not want to do constructor injection in my base controller.
A better practice in MVC it is to use constructor injection over property injection. Why did you make your choice like this ?
Using Constructor Injection you states that all dependencies in constructor are necessary for the class to do its job.
Property injection means that the dependencies are optional or that there are the local defaults implementations, so all will work even if you don't provide necessary implementations yourself.
You should really know what you're doing using Property injection or you have no other choice, so the safer approach is to rely on constructor injection.
Now I'll give you my point of view. Other may have other opinions.
DependencyResolver was introduced in MVC 3 for "convenient" service location but for me it's a regular Service locator which for me is also an anti-pattern http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. I don't use it because I don't like it and there is no benefit in using it.
I prefer to user my controller factory like before and pass the dependencies through constructor.
More the IDependencyResolver has somme issues with some IoC containers (I don't know if it's the case with Ninject). You can read more here : http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html
If you need the same dependency in each controller then there seems to be something wrong in your design. Most likely you are handling some kind of cross cutting concern in your base controller. In this case Doing property injection is just treating sympthoms instead of cureing the disease. This should rather be handled by an aspect (e.g. a filter or an interceptor) so that you do not have to pollute your controller with something that does not belong there.
There are many ways to skin the cat they say. You could use conventions-based bindings with .WithPropertyValue() or with .OnActivaction() (as described here).
public class ControllerModule : NinjectModule
{
public override void Load()
{
// Get all controller types derived from the base controller.
IEnumerable<Type> controllerTypes = // ...
foreach (var controllerType in controllerTypes)
{
Bind(controllerType).ToSelf().InRequestScope()
.WithPropertyValue(...);
}
}
}
You could create your own custom implementation of the IInjectionHeuristic interface as described here or your own custom implementation of the IControllerActivator interface.
public class CustomNinjectControllerActivator : IControllerActivator
{
private readonly IKernel kernel;
public CustomNinjectControllerActivator(IKernel kernel)
{
this.kernel = kernel;
}
public IController Create(RequestContext context, Type controllerType)
{
var baseController = kernel.TryGet(controllerType) as BaseController;
if (baseController == null)
{
return null;
}
baseController.UserService = kernel.Get<IUserService>();
return baseController;
}
}
Heck, you could even use the service locator pattern if you are comfortable using it.
public IUserService UserService
{
get { return DependencyResolver.Current.GetService<IUserService>(); }
}
You should choose whichever solution is easiest to implement, test and maintain, and of course provides the desired behavior.

Resources