Good way to define module in Spring mvc - spring

Im using Spring mvc 3.1 version and Apache Tiles 2.2.2 version i'd like to define some common modules in my applications pages.
For example i want to define a menu in the top, a left side and right side,.. all my page will display these block.
Im using Tiles to define the differents blocks, some part of tiles implements ViewPreparer because i need to get information from database, know if the user is logged,... each tile is responsable of its own module(get data, set attribute for the jsp...).
Is it a good way to create some modules ? Or should i define a controller who will define the data, the business...to all page modules ? (left side, right side, menu...)

If your common module only consists of HTML then it doesn't matter how you do it. Tiles template is sufficient.
The problem is if the common module need models to be populated on the controller. You don't want to duplicate the code on every single of your controller which view includes the common module.
One approach you can take is subclass your controller with a class that populates common module model, eg:
public class CommonHandler {
#ModelAttribute("loggedInUser")
public UserInfo getLoggedInUser() {
// check and return logged in user if any here..
}
}
#Controller
public class MyController extends CommonHandler (
#RequestMapping(..)
public String myHandler() {
// ...
}
}
In above example if myHandler is requested, getLoggedInUser from CommonHandler class will automatically be called to populate loggedInUser model. In your view you just obtain it using ${loggedInUser}

When using ViewPreparerSupport which implements ViewPreparer, it works very well :
#Component
public class MyPreparer extends ViewPreparerSupport {
#Autowired
private UtilisateurService utilisateurService;
#Override
public void execute(TilesRequestContext tilesContext,
AttributeContext attributeContext) {
//information to set for the jsp tile
}
}

Related

Is it possible to inject objects into templates in a transversal way?

I have multiple templates, but in all I need to know if the user is authenticated or not to know whether to show the access button or exit.
Currently in each controller I must send the object of the user entity to the data model for the template, but this means initializing the user service on all controllers.
Is there any way to intercept the controller and automatically inject the user entity into the model without affecting the normal use of the model in each controller?
I currently know that it is possible to use the aspect interceptor to control the use of controllers from their classes and their functions, but I don't know how to intercept the "model" argument and fill it with the entity.
You could use #ControllerAdvice with #ModelAttribute. Just create a class like this:
#ControllerAdvice
public class ModelAttributesForEveryController {
private UserService userService;
#Autowired
public ModelAttributesForEveryController(UserService userService) {
this. userService = userService;
}
#ModelAttribute("userEntity")
public String userEntity() {
// Here goes your logic to get the User entity
return theUserEntity;
}
#ModelAttribute("isLoggedIn")
public String isLoggedIn() {
// Here goes your logic to determine if logged in or not
return isLogged;
}
And then you can use that model attribute named userEntity in you template like any other attribute
For example using the isLoggedIn model attribute (a very dummy example):
<button th:if="${isLoggedIn}"> Exit</button>
<button th:if="${!isLoggedIn}"> Sign In</button>
If you just need to know the authenticated state, you can add the thymeleaf-extras-springsecurity5 dependency to your project, then you can use sec:authorize="!isAuthenticated()" to check logged in or not.

What is the best way to instantiate service layer classes?

I've been using laravel for a long time. However, I need better the way I structure my projects.
Sorry for my english, I'm from Brazil.
the structure of my project is: router -> controller -> Service -> Repository -> Model. I place all application logic within the service layer.
My problem is that my services are coupled. And in many situations I'm having circular dependency.
and I use dependency injection to use class instances.
My controllers
class StudentController extends Controller
{
public function __construct(StudentService $studentService){
$this->studentService = $studentService;
}
}
class EnrolmentController extends Controller
{
public function __construct(EnrolmentService $enrolmentService){
$this->enrolmentService = $enrolmentService;
}
}
My services
class StudentService
{
public function __construct(EnrolmentService $nrolmentService){
$this->studentService = $studentService;
}
}
class EnrolmentService
{
public function __construct(Enrolment $studentService){
$this->studentService = $studentService;
}
}
In my example, I need to create an enrollment when registering a student.
You need to change student data when editing an enrollment. The problem is that since one class depends on another, I have a circular dependency problem. I know I should create a third class to try to work around the problem. What I want to know is if this structure of mine is correct. How could I improve this?

How can I put an instance of an object as session attribute in a Spring MVC project?

I am working on a Spring MVC application and I have the following problem.
I have this RegistrazioneInfo class that contains some information inserted into a form by the user:
public class RegistrazioneInfo {
#NotNull
#Size(min=16, max=16)
private String codiceFiscale;
String gRecaptchaResponse;
public String getCodiceFiscale() {
return codiceFiscale;
}
public void setCodiceFiscale(String codiceFiscale) {
this.codiceFiscale = codiceFiscale;
}
public String getgRecaptchaResponse() {
return gRecaptchaResponse;
}
public void setgRecaptchaResponse(String gRecaptchaResponse) {
this.gRecaptchaResponse = gRecaptchaResponse;
}
}
Then I have this controller class:
#Controller
public class RegistrazioneController extends BaseController {
private RegistrazioneInfo registrazioneInfo;
...............................................
...............................................
...............................................
}
that contains some methods handling request towards some resources.
Ok, my problem is that I want to use an instance of the previous RegistrazioneInfo class as session attribute by the use of the #SessionAttributes Spring annotation as shown here: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-sessionattrib
My problem is, in the previous example do something like this:
#SessionAttributes("pet")
public class EditPetForm {
// ...
}
So what exactly is pet? I think that it is something like an id that identify the object that have to be used as a session attribute or something like this. How can I say to put an instance of my RegistrazioneInfo as session attribute?
#SessionAttributes is declared in a Controller Class (#Controller), so on the class level.
Pet is an Bean Object that persist in HttpSession
From the documentation:
This will typically list the names of model attributes which should be transparently stored in the session or some conversational storage, serving as form-backing beans. Declared at the type level, applying to the model attributes that the annotated handler class operates on.
(emphasis is mine)
Also note that, as indicated in the documentation, you should not use that for "non temporary" elements.

Define validation properties outside Panel in Wicket

I need to define Wicket validation messages in .properties file of a page for a reusable panel. I will give an example (code snippets below):
MyPage class contains MyPanel with a fragment MyFragment in which there is a component called MyComponent (TextField of a type BigDecimal).
I need to define 3 instances of reusable MyPanel on the MyPage and I need to define a validation key for the MyComponent in MyPage (because they are used in a different context).
class MyPage extends WebPage {
public void onInitialize() {
super.onInitialize();
add(new MyPanel("fuelConsumption");
add(new MyPanel("populationGrowth");
add(new MyPanel("averageGrade");
}
}
class MyPanel extends Panel {
public void onInitialize() {
super.onInitialize();
Fragment fragment = new MyFragment("fragment");
add(fragment);
}
class MyFragment extends Fragment {
public void onInitialize() {
super.onInitialize();
add(new MyComponent("component");
}
}
class MyComponent extends TextField<BigDecimal> {
}
}
So, I need to add a validation messages for all 3 usages of the MyComponent field of type BigDecimal into the MyPage.properties, something like:
fuelConsumption.fragment.component.IConverter.BigDecimal=Fuel consumption must be a decimal
populationGrowth.fragment.component.IConverter.BigDecimal=Please check the population growth format
averageGrade.fragment.component.IConverter.BigDecimal=This is not an average grade!
I deliberately use different kinds of validation messages, I don't want to use a single one with configurable parameter
When I add MyPanel.properties and put a line like this:
component.IConverter.BigDecimal=Component is not a valid BigDecimal.
it works fine, but I really want to specify it outside the reusable panel (so that the panel may be used in other ways and meanings).
How would I do that?
When I try to add the lines above, it does not work, nor in any way I tried, like omitting the "fragment" or "component" from the properties string. Nothing helps.
Thanks for any suggestions!
Your solution looks good to me.
Enable debug logging for org.apache.wicket.resource.loader.ComponentStringResourceLoader to see which keys are searched.

ASP.Net MVC 3 - instantiate data context class in BaseController

When adding a controller in ASP.Net MVC 3 using "Controller with Read/Write actions and views, using EntityFramework" as template, it generates a class as follows:
namespace Project.Controllers
{
public class Default1Controller : Controller
{
private ProjectEntities db = new ProjectEntities();
...
}
}
Now, I would like to know if it would be a good practice to change this so that my Controller would inherit a custom base controller that would instantiate ProjectEntities. It would look as follows:
BaseController:
namespace MatchesHorsConcours.Controllers
{
public class BaseController : Controller
{
protected MatchesEntities db = new MatchesEntities();
...
}
}
Other controllers:
namespace Project.Controllers
{
public class Default1Controller : BaseController
{
...
}
}
This technique is useful when you need logic in your master page (for example, to dynamically render menu options). Read about this here: http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs
However, in general this is not a good technique. I would recommend using dependency injection (Ninject works well with MVC and is easy to implement)
No absolutely not. It makes totally untestable. Please use repository pattern and constructor injection if possible: Repository Pattern vs DAL

Resources