Springboot and Thymeleaf very long url's - spring

While working on my project I encountered an issue with the URL.
I have around 10 entities and all working with the primary key in the URL to do things like update, create and read.
Example url:
"/project/projectID/clust/clustID/tr/trID/story/storyID/design/designID...."
The more objects there are, the longer my URL gets.
When i'm at design I only need the ID of story to create/update the design and not all the previous ID's and URL part.
The only reason I keep extending my URL is to have navigability for the user to go from design to project for example.
Each method in my controller has a lot of #Pathvariables for all the ID's and I keep giving all the ID's to the model.addAttribute to the view. The reason for this is to build the URL in a button on the view when a user wants to navigate to somewhere else.
Long story short:
My URL keeps getting longer and longer, the only reason for this is to navigate.
Controller methods have a long parameter list of #Pathvariables and a lot of model.attributes to put all the ID's in the Thymeleaf view.
I'm using thymeleaf with Spring Boot.
All my entities are bidirectional. So If you have a design, it is possible to retrieve the project.
How can I resolve this 'problem' and still keep the navigability?

Related

Spring Mvc passing model data to multiple pages before persisting

I am in the process of creating a simple application with Spring Mvc and thymeleaf and I am currently thinking of what functionality I want to implement but I don't know exactly how to do it.
Let's say I have a model class Person. Regularly I have a form and a controller where I am passing the new person object and persist it with JPA.
No problem there but what if I want to have a page that I give some of the person basics info and then hit the "next" button and give some additional information. Then hit "next" again, review the data and hit "save"?
You can do it by integrate Spring Webflow in your project.
Webflow is basically extensive part of WebMvc. Webflow has some configuration that, where you have to start and where you should go. If you have 5 page and you would like to all these data will put into database in one process then Webflow will help you. One more advantage is, you can add validation in particular pages and particular means you have five model and all these model will work in one flow.
Read more, https://projects.spring.io/spring-webflow/
I have not used Thymeleaf, but usually this kind of problem can be solved using some of the following methods or something similar:
1.) Save the unfinished data to database using the same schema or some other schema for this (or in session; in general sense, save it somewhere on server side). Problem with this is how to get rid of abandoned data where user has not moved to finish.
2.) Drag the data from page to page with request parameters. If the requests are of type POST then just in POST body, if they are type GET then as query parameters. Problem with this is it's not very clean.
3.) Don't do full page requests. Solve it with some front end solution using Javascript. Depending on the app it might or might not be possible.
4.) Do full page requests but still solve it in front end using local storage or session storage. Similar problems as with keeping the data in server side session.

Extract HTML Helpers from Razor views

Situation
We are rebuilding a web application (winforms), from the ground up. The old application will keep running, when the new one is released. This means that the new application needs to talk to an old database, I can't change anything there. The new application will be build with .NET Core 2.0 MVC.
The old application uses a custom translation database table, based on a language-id and translation-id. Very straighforward.
Problem
The old application made a database call for each translation, over and over again. Because the new application needs to reuse this table, i'd rather have a smarter system. Because of the amount of translations, I don't want to get all data on each page request. I also don't want to make a database-call for each translation.
Idea
My idea is to create a custom HtmlHelper (or dependency injected translation instance, but that might be harder in this situation) which only needs the translation ID. The helper will get the language from a cookie. This way, we can simply use the following code in our views:
#Html.Translate(1337)
What i'd like to achieve, is to use the first Translate-call to scan the RazorView for all Translate-calls (with their parameters). This way, I can use a Dependency Injected Scoped instance to save all the translations to. Which means that I only have to make one database call for each requested view.
Actual question
Does this sound like a good idea, and will this be doable? I searched through the MVC source code, but can't find a way to achieve something like this. The RazorView instance in the IHtmlHelper does not seem to have list of IHtmlHelper's or something...

Dynamically update the UI when selecting a date

I'm trying to learn some basic knowledge of jsp, suppose that I have a project, in this project, after signing in, I have a Main.jsp with a calendar or a dropdown list in it, when selecting a date, I'll change the UI based on the data from database.
I can put all relevant data into request after signing in, and use JSTL in Main.jsp, but if the data is huge, this doesn't sound like a good idea, right?
Back to the old age when there's no JSTL or AJAX, how does jsp developer deal with this? And what is the best practice nowadays?
Thanks.
If you are talking to render about without JSTL or AJAX, the only option i see is to submit/send the form to server and get it back with updated view, but yes it will cost a lot in terms of performance.
I think for your use case:
1) you can get the data from server via AJAX on every update,
2) or, if the data is not customer dependent and is fixed in terms of UI, you can load it lazily in background, and change the view immediately on the user action.

what is the correct approach in order to host / integrate / show my existing MVC3 project inside orchard?

I've an existing MVC3 project that implements a certain functionality, this project has it's own views, and a separate Database.
now I'm required to use the same functionality inside one of my orchard project,so I thought that I can host this solution in somewhere and view it inside an iframe or something.
Am I thinking right?,
is this the correct step to take in order to achieve this requirement inside Orchard?
to make it more clear, all I need to do is to view this solution and interact with it's controls and views from a hosting page inside orchard, and the subsequent requests should be handled by my solution in order to hit it's own data store and get back with the requested data in order to be displayed to the user.
any help would be appreciated.
Update:
thanks for Bertrand Le Roy for his answer, I can now view my solution inside my
orchard website.
I came in to one more HUGE problem, which is that my application can no longer connect to my external database.
I've a DB that is hosted in some where else, and I'm using EntityFramework to deal with it.
the problem is that if I put the connection string inside my module web.config, or main orchard web.config, I run into several types of errors like:
"System.Reflection.TargetException: Object does not match target type."
or
"System.Data.MetadataException: Unable to load the specified metadata resource."
My question is: How could I pass my connectionstring correctly to my solution, assuming that I'm using Entity framework as my ORM.
Many thanks.
You will need to put it into a module.
You will have to move route definitions to a Routes.cs file (look at any existing such file for examples).
You will also need, in order to access your data store, to opt out of the ambient Orchard transaction around the data access code (using (var scope = new TransactionScope(TransactionScopeOption.Suppress))).
If you are using dependency injection, you may have some work to move that to the Autofac-based way of doing things in Orchard.
If you want your work to appear seamlessly in the Orchard admin, you may want to decorate your admin controllers with the Admin attribute. If you want your front-end to use the current theme, you'll have to add Themed attributes and maybe refactor your views so that they only emit HTML for the content zone instead of for the whole page.
Add a manifest (module.txt) to your module folder and you should be good to go.

Coldfusion, whats the advantage of front controller design over page controller?

I'm from a non-computing background and I'm struggling to getting my head around MVC design approaches and frameworks in general. I "get" code re-use, and separation of logic from display, and I "get" encapsulation and decoupling, but I don't get this.
At the moment I simply put everything in root, a separate subfolders for images, cfcs, and _includes, all database interaction via cfcs. I do all my processing at the top of the page, then a comment line then display/page layout below that.
Most of the frameworks I have looked at seem to favour a front controller, so my simplistic version of a top controller MVC design would be a subfolder for cfcs, controllers, and views and a big switch statement in index.cfm
<cfif not IsDefined("URL.event")>
<cflocation url="index.cfm?event=home" addtoken="No">
</cfif>
<cfswitch expression="#url.event#">
<cfcase value="home">
<cfinclude template="controllers/home.cfm"/>
<cfinclude template="views/home.cfm"/>
</cfcase>
<cfcase value="about">
<cfinclude template="controllers/about.cfm"/>
<cfinclude template="views/about.cfm"/>
</cfcase>
</cfswitch>
.. but what real advantage does that give me over a page controller design? Unless it's just the kind of sites I write, I always seem to find that the controller logic is specific to a view, its not like one controller could fit several views or several controllers could output to one view, so what would be the point of separating them?
The light hasn't come on for me yet, any pointers?
By "top" controller, I think you mean "front" controller, a single point of entry for requests into an application. As #bpanulla wrote, most ColdFusion frameworks use this design pattern. This becomes particularly interesting with URL rewriting, where it becomes easy to have search engine safe URLs by intercepting the a URL (e.g. domain.ext/i/am/friendly.ext) and routing it to some standard file such as index.cfm while making the requested URL a parameter (often as a request header). This also makes site redesigns where URLs change easier because it lends itself well to aliasing or redirects.
As far as controllers are concerned, they are usually tightly coupled to a particular URL or URL pattern. It's possible be more loosely coupled with controllers, but in practice I find that's an emergent property after multiple refactorings. What should be underlying the controller is one or more calls to a service layer that talks to the database, executes business process, creates stateful entities, etc... Then the controller receives the service layer's outputs and places them into whatever mechanism (e.g. an event object) is used to pass data to the view(s).
It's the service layer that's meant to be reusuable not the controllers. The controllers are merely an extension of whatever framework an application works within. The idea being that you should be able to switch frameworks with very little impact to the views and service layer. The piece that needs to be touched are the controllers.
So a given service object in a service layer should be able to service multiple controllers. For example, consider showing a logged in users' information as a widget on a site. There might be different pages served by different controllers, but each would call the same service object to get logged in user data that presumably might be given to the same view that renders the widget.
Update: Front Controller Advantages
Security: centralized authentication and authorization.
i18n & l10n: inject the right language pack into the request globally
Process Orchestration: think multi step checkout process for a shopping cart where you don't want the back and forward buttons to work - by routing everything through the front controller you're able to enforce what step (i.e. the state)
Logging & Tracking: easily add Google Analytics or other request tracking to a site by making the addition in just one place
Error Handling: centralized behavior
Now many of these items can also be done using <cferror> and Appplication.cfc, but I find it easier to have one centralized point.
Useful Links
http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
http://msdn.microsoft.com/en-us/library/ff648617.aspx
You actually implemented the crux of Fusebox (http://www.fusebox.org/) with what you wrote. There's nothing wrong with that, and most of the ColdFusion community used something similar to that for many years - Fusebox was the most-used CF framework (in my experience) until just a few years ago when ModelGlue, Mach-II and the other second generation CF frameworks came about.
One thing I can point out is that your approach to controllers (as .cfm files) actually does not enforce encapsulation in the typical OOD fashion, with specific arguments going to an object method call. Unless you are extremely dilligent, over time your .cfm controllers may wind up accumulated a large number of undocumented parameters that alter behavior to solve one problem or another.
With the various frameworks you also get nice features like Application, Session, and Request specific code (onApplicationStart, onRequestEnd, etc). But you can always get those through a simple Application.cfc.

Resources