I have a legacy banking application coded in Struts 1 + JSP
Now requirement is to migrate the backend (for now MVC) to Springboot (MVC).
Later UI (JSP) will be migrated to angular.
Caveats
1.) Backend is not stateless
2.) Lot of data stored in session object
Approach
Have 2 application running in parallel (Struts and Spring), and share the session object between the two, Storing session in Database, in memory (Redis) etc. This means lot of code changes, as currently session is manipulated across layers of JSP, action, service for every update/fetch
Build complete Spring application and then make it live, which is again not feasible and we can't have user waiting.
Marry Struts 1 and Spring in same app and later Divorce them, and removing struts components progressively.
Question
Is it feasible to have Struts 1 and Spring together in same web application.
Can 2 different servlets (ActionServlet & DispatcherServlet exists together), possible if i have 2 different context paths for spring & struts
Currently focus is to migrate MVC layer, service layer will not be an issue.
Also if i need to keep backend design of API to support REST in future, possible if i can design in such way.
Current
JSP -> Struts 1 MVC -> Service Layer -> DB
What we can built
JSP -> Struts 1 MVC <-> JSON Object parser <-> Spring REST MVC -> Service Layer -> DB
Future
Just remove JSP -> Struts MVC
Angular (or any other framework) -> Spring REST MVC -> Service Layer -> DB
My friend, it is so good to read your question! I lived the same hell you are about to enter using the very same stack...
Approach 3
Honestly I would never try it. The reason would be simple, we wouldn't want the risk of having old project and new project mixing with each other. Libraries from the legacy are very likely to conflict with libraries from the new project (same libraries, different versions) and you would then need to either refactor old code to allow use of the new version, or change libraries completely.
When migrating, you will want to keep your work on the legacy code to a minimal, to none if possible.
Approach 2
The perfect one, but as you said, it won't pay the bills. If you have the cash to work on it, then great, go for it, otherwise, you are for...
Approach 1
Strangulation, that's what worked for me. Start with a working shared login and then move to small functionalities. Think of a tree, you start by removing some small branches, them you move to nodes, until you are able to cut everything. As you remove the small functionalities, they should be made available on the new product (obviously you can't disrupt service otherwise you would go with approach 2).
More specifically, my suggestion is:
Back-end
1) Get the login working. In my case, legacy was all about session, but we didn't want that on the new product. So we implemented a method on the legacy code during login, which would call Oauth from the new product and store in the database the login information, just as you mentioned. The reason for this is on the front-end part of my reply.
2) Define how your legacy and back-end will live together and the resources to have both of them working (ram and CPU to be more precise).
2.1) If by any chance, your legacy runs on tomcat with custom libraries, you might have problems running your new product in a different context. If that happens, my suggestions, go for Docker (just get a close look on memory usage and make sure to limit them on your container(s)).
3) Start very small, replace functionalities related to creating new stuff which hold little to no logic (small crud, such as users, etc) then move to things that have mid-sized logic or that are really ugly on the legacy product and are used on day-to-day basis by your end-users.
4) All of the rest (by the time I left the company, we were not in this phase yet, so I can't provide much info on that).
5) Don't treat this project as a migration only. Get everyone on the page that this a new product. Old code should not be copied and pasted, it should be understood and improved using best practices.
5.1) Unit and integration tests as soon as possible, if your legacy have them, GREAT, compare results to make sure your refactoring didn't break anything or changed the expected outputs. THIS IS ESSENTIAL.
Front-end
1) Once you have the "unified" login working, you will be able to load the pages from the new product as if they were part of the legacy (you could even add a frame on the jsp of the legacy that will load your angular page, we did it and it works like a charm).
1.1) Not cute from a UI/UX perspective to have old and new pages, but it will add value to end-user and provide you with feedback from them once you release the pieces to production. Since your legacy now have access to the token (or whatever auth method you are using, that will be feasible).
2) Define the styles from the beginning. Don't get the job of UI/UX to later (like my team did). The sooner you figure out things such as colors, design, icons, etc, the less time you will waste on meetings that should discuss the release and its impact but are wasted discussing "this is not the color I wanted" or similar. Honestly, get UX defined before UI and make that crystal clear.
3) Design it as if you were designing a micro-services front-end. You might take a lot of time to get to that point, but if and when you do, the migration from the new architecture to micro-services will be much less traumatic.
Culture
I don't know the culture of your workplace, but mine was far from perfect, old people with old thinking into their comfort zones.
Get to change the workplace culture to adapt to what we currently have on the marketplace, old people sometimes tend to resist change, specially when they are technical and do not update on what's new out there. It will make much easier to replace people when they leave the company (because people do move on).
I heard they are still trying to run Scrum (as I mentioned I am no longer there), so there was a huge headache for developers defining What and How the migration of functionalities will take place.
Those are my two cents, hope they help you in some way, and I wish you the best of luck.
Since option 2 is not considerable because of business feasibility let’s talk about the other two.
Approach 1
If you push your session state as far back as appropriate datastore ( Redis/Memcache) and use a transparent mechanism to get the
session data and update any changes made by app server then you would not need to change any code interacting with session.
Any call to get session object from any piece of code in your application is delegated to container and it is container which
provides you with the object ( usually a mapping of sessionid and object is maintained). For container such as Tomcat I am aware of
session manager which can be replaced by just putting the jar in the container and pointing the config to the backend store. I have used
memcache based session manager successfully in production for a high traffic internet application.
Check this for Redis (https://github.com/pivotalsoftware/session-managers) and Redisson Tomcat manager (https://github.com/redisson/redisson/tree/master/redisson-tomcat), Memcache (https://github.com/magro/memcached-session-manager)
Using this will tranparently fetch/store session in respective datastore without changing any session related code in your application.
So the request with session id in cookie can land up on any of the tomcats ( hosting struts or Spring MVC app) and get the session
fetched from the backend store, made changes upon and tranparently stored back.
Approach 3
Is technically possible ( they are after all different servlets with different configuration responding to different url patterns)
but opens a lots of problems areas in terms of
dependency jars conflicts. But if you freeze the library versions of both the framework during the migration and somehow don't get any
conflict with a certain versions of your mix then it can be worth trying as eventually the struts library and it's dependencies will go away.
As for the Angular part - you can still still have the user info in the session and rest of the stateful interaction will need to be designed
in a series of stateless ( stateless on the middle tier as eventually you will need some state - just that it will be pushed to the database) interactions.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Is it a good practice to deploy web services separately or should they be part of the web application? For instance, I am developing a spring rest based web service. The function of this service is to, let's say, to get user data.
Each webapplication that queries this web service has it's user data in different schema. So, now the webservice will need to know who is calling it - is it Appilcation A or Application B? If it's AppA, then it should get data from Schema A, if it's AppB, then its another schema. Note, that AppA and AppB are just the same code packed into two different wars and the schema they are supposed to query is supplied from properties file.
In a situation like this, does it make sense to pack the webservice with the webapp code and deploy it under different contexts, so it becomes a duplciate service running in a different context. Or, should it be deployed separately and somehow the AppA and AppB are supposed to identify themselves to this web service?
I prefer below approach, which is in use for 50K concurrent users.
Make sure that each web service encapsulates both UI and Schema independently by executing required business use case. Each web service will have all three layers - Model, View and Controller for that business service. That means your App-A is one web service & App-B is other web service.
All web services will register and un-register with Master web service. Master web service is responsible to redirecting user request to appropriate web service like App-A OR App-B.
You should have cluster of Master web service & cluster of individual web services - App-A & App-B
In this approach, your schema can reside on different database instead of single database
Advantages of this approach:
Each web service can scale horizontally. Just add additional VM nodes if you want to increase the scale.
If you have different schemas on different databases in different locations, you are avoiding network performane bottlenecks in OLTP queries (Online transaction processing queries).
Disadvantages:
I see only one disadvantage since Master Web Service acts like a Facade and it should know the internals of individual web service. But it's not a drawback for the advantages it is offering if you consider the trade-off.
I have no idea about your business requirement to maintain different schemas for user data and going with webservice.
But instead of maintaining multiple wars with same code, i would suggest you to configure multiple datasources within the application and switch to datasource as per your requirement.
This link may help you to configure multiple DS
If you fallow aforementioned logic, you may end up with single deployable context.
Still want to stick with multiple wars as webservice, i would suggest you to have look at SpringBoot simple, container less deployable and scalable.
It is a matter of opinion, both choices are okay. You should take into account the usage of the service, scaling concerns etc.
You could look at Microservices as an idea, but it has to make sense from your standpoint.
About the two different apps: if the differences are only in configuration, try externalizing it (23. Externalized Configuration). This way you can have a single artifact being deployed twice.
Given that scenario, it is a good practice having only one web service, in this way you improve the maintainability of the system because you don’t have the same code twice. If you have in the future other new similar app you don’t have to implement a new service.
Approach 1:- (Preffered)
You should have a single web application in which will have the entire code for application UI and Repo/data interaction.
Based on the type of request dynamically switch the data source as needed. You can have at look at Spring Dynamic datasource routing here
Approach 2:-
In case your UI has a completely different type of interactions managed by different teams, it makes sense to have separate UI components and the backend web services maintained at a same location.
Again based on the type of request you can dynamically route the datasource.
Hope this helps :)
my inputs:
1) Any specific reasons to build 2 different wars for same code? Is it only because you have two different data sources for each of them?
Why cant you have single application deploy with some parameterized mechanism in each request to identify which schema to get data from?
2) Why do you need a web service in first place? Why not application hook directly to database it needed.
3) Is underlying database transactional DB or some historical data? How about merging both schemas in one as one-time effort OR using some sort of virtualized views which picks data from 2 schemas based on input parameters.
***** edited after Jay's inputs:
My suggestion will be to have web service deployed separately from 2 web apps because it provides single place to manage code in long run. I have following additional suggestions:
Define your own headers in SOAP XML Schema which can give you both appContext(application making call) as well as userContext(user). Give a good thought on this aspect keeping long term view.
Keep SOAP request-response stateless which will give you scalability. Dont maintain any state of SOAP request at server side.
I have in past used a data virtualization solution (CISCO Composite)..what benefits it provides: if there are two (or more) data sources containing similar type of data(entities), it can join,cleanse & merge it virtually and expose it as REST/SOAP based web service. Try evaluating this option as well.
What it can further help if in future you have other consumers to access your information using plain SQL/JDBC call, they will be able to do it...also data virtualization solutions support many other interfaces to consumers like Hadoop, OData etc...again it depends on budget and other constraints of project...I am not sure if there is any effective open source data virtualization solution available or not?
Personally, in my experience, it's a lot better to have them separated, it usually depends on how big and how critical your main project is.
But even if at the beginning your project isn't that big and there's only 1 person working on it, later on, as it continues to grow, if you have microservices for all the things your main project do, it will be a lot easier to maintain, rather than having many people working on the same code handling many versions of an unique project, handling many small projects is less confusing and errors are easier to find.
Plus if something fails, you can have 1 microservice down while your main still runs without interruption, it will only by denied of 1 service, instead of having everything down while you fix it.
High availability is very important in production, and having them separated helps with this.
Given your situation I'd advice going with ONE webapp (one "project") with some caveat and then consider one of the two solutions:
1) Given you are using spring, I'll assume (hope) you are using maven as well..
Make a different compilation goal and make it so that, based on the goal invoked to produce the war, the relevant properties file is different..
This way you have ONE webapp, and based on the compilation (or rather based on the properties file tied to that specific compilation) you will obtain a war tied to a specific environment&schema... You deploy an individual war for each webservice with a clean separation, though the root code is the very same and it's only one application... [CLEANER SOLUTION]
2) Make it so that you don't only get the json request but also the https certificate of the sender (thus you identify a specific "webapp" based on the https certificate exposed), and based on the certificate AND The source of the request, you ensure the source as "qualified" to receive data from schema X rather than schema Y.. You deploy ONE war only that will, at his own discretion, apply logic to reroute your "user data fetch query" to one database or the other [I DISCOURAGE THIS PRACTICE]
of course there are other approach as well, but I think these two are the most feasible..
It really depends on what you want to achieve.
If you want to encapsulate the database/schema/table, then it should really be one service for each application. The main advantage of doing this is that you could swap the database later on if there is some problem with the current one, it also simplifies caching and invalidation, etc etc.
If the database/schema/table is not encapsulated anyway, then the single service is much easier and better. Each web application just have to identify themselves, and each of them will get exactly what they need. This could be achieved by putting the query/schema information in property file, or creating db views with the same name as client, etc.
If we were to go for this approach, a question will pop up. Why bother having this layer at all? Couldn't each web application just query the db directly? If the answer is yes, then just remove the whole layer completely.
You are trying to implement a Data Provider, or DAO as a service.
To make it -
Simple
Scalable
Maintainence-friendly,
Adaptable
You can simply have a single webservice, deployed outside the WebApp(s) and driven off configuration. The configuration itself can be stored as property file, or from a DB. The identifier for the client should be being passed in the webservice request.
This is actually a pretty standard approach implemented to enable optimizations at the Data tier outside of DB, like caching (again driven of configuration), expiry, pooling, etc.
The other option, to include as a shared jar within the webapp, yes, has advantage of code-reuse (which you get with externally deployed service as well), but the following disadvantages outweigh the option.
Coupling
Employing optimizations are difficult
Release management (this also depends upon how your code is organized)
Versioning.
Hope it helps.
I would deploy to one instance. No matter what. Of course, there are circumstances where it may be necessary to deploy separately. From a best "coding" practice, one instance should be used to allow for "right once, use many".
Then...
Define different XSD's for each AppA, AppB, etc. Marshall accordingly.
Or, use Groovy to marshall appropriate objects as json or xml.
We're building a java web application where each customer will have an instance of it with it's own database schema.
It will be managed by my company so I would like to know what is the best approach to have several apps instances running on the same Tomcat runtime since we tried to run 3 instances on a single Tomcat and it ended up on an Out of memory exception.
We considered to run multiple tomcat instances in the same server but we haven't already tested it. Also we are considering to have a separate server for each customer.
From your experience with similar scenarios, what is your opinion?
EDITED: This application can't be multi-tenant since there will be code customizations in some parts of it as well as some other business facts that require an application instance per client. So please the application architecture is not the subject here.
Thank you,
Gyo
You want to use multi tenant architecture. There will be only one database and web application instance, and every record will be qualified by the 'owner' company. You can use the subdomain/domain which the client uses to access your application to differentiate between them.
Simplistically, you add a 'domain_id' column to every table and you have a 'where domain_id=?' in every query. Each user will have an associated domain_id which you will pick up on login and put in session. In reality there will be other considerations.
EDITED: Based on the edit in the question, here is additional part to the answer.
In multitenant architecture it is possible to customise every instance without maintaining separate codebases. Some of the customisations can be part of the 'profile'. This is suitable for data values and flags, like currency, date format, etc. The case where new functionality specific to a client is required, this can be achieved by supporting plugins.
Taking a one time pain to fit your solution into a multi tenant architecture will be better than the on going pain of maintaining several separate versions of your code for each client. You might want to read up on the topic of 'technical debt'.
An ERP is a complex case of a business application, and you can get inspiration from reading the OpenBravo Trial FAQ to get an idea of what we are saying. Openbravo is open source and you may get technical details by looking at their code.
My Opinion is exactly the same as Kinjal Dixit one. Your approach is wrong and will be an huge waste of resources.
If you want to be able to deploy different version of the web-app for the same server you will have to isolate the class-loading of each app and this will imply an huge memory consumption. Otherwise if all web-app will always be the same there is no interest to deploy it many times.
Having a separate server for each customer will also be a waste of resource (multiple instance of JVM, multiple classloading of the same libraries, multiplication of the number of thread and so of the cost of scheduling) and will significantly complicate the deployment, especially if you plan some clustering strategy where the load balancing will probably become a hell
Moreover if you want to have some specific feature for a given client it will also become a hell to manage / deploy / upgrade, etc...
Multi-tenant architecture does not necessary imply to share the database (you can have a DB instance per client and dispatch the request with an interceptor at low level) however sharing the web-app is an absolute necessity.
I'd also advice to provide some kind of configuration to allow to enable custom features for a given client.
I worked for a company where we encountered exactly this problem (expose a legacy web application as a SAAS one) we started by deploying one web-app per client, spent huge time in various optimization (including class loading factorization) to reach the "huge" number of 14 customer per server.
This was far from our performance expectation and we finally switched to a multi-tenant architecture, but keeping one DB instance per customer to avoid the important cost of data-model refactoring. The new deployment was able to handle more than 100 customer on the same server with incomparable performance.
EDIT (according to question update)
If you absolutely want to avoid multi-tenancy then i'd recommend to use only one servlet container (tomcat) per server. In this case you will have to let the default web-app classloading isolation (as you will have custom code in different instances) which will imply a high memory footprint. You should however put all common libraries in the common/lib tomcat directory to factorize their loading ( see http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html).
I am trying to implement a reasonably complex page flow (100+ pages) as a traditional web application. I found a few options, but none of them are 100% convincing
Harcode the flow into the controllers, do redirects, etc. This is obviously not the best thing for maintenance
JSF not only handles the flow, but also requires to use JSF as the view technology. I don't like this lock-in
Spring web flow. The current version 2.3.1 defines flows in XML that is not easy to maintain. The upcoming 3.0 release promises to define flows with annotations in pure java, but it does not even have a timeline. Additionally the project development slowed down significantly in the past years.
GWT and Vaadin's concept is closer to a traditional desktop application then to a web application, that is really convenient to use, but it wont fit to my project.
Additionally I found dozens of abandoned projects like this: http://javasteps.sourceforge.net/
I am wondering why all these projects are abandoned, what is the way to implement a complex page flow in 2012?
Personally, I'd recommend Single Page Architecture:
Architecture of a single-page JavaScript web application?
I'm not sure if that is feasible or not with your application. I've used all the flows you mentioned above and am currently working on a single-page application and I love it. We're using Dojo on the client-side, which calls a REST API on the server. It's been pretty nice.
Vaadin is pretty solid too and is much easier to set up than just bare-bones GWT. If you have a lot of UI guys on your project that like to code in CSS and Javascript, they'll hate that approach though.
Spring Webflow is pretty solid actually. I haven't looked at it in a while, but when I was using it, it got the job done for what I worked on at the time.
This is really late but I don't see a satisfactory answer to this question and would like to share an approach I had tried in a recent project which I feel is better than the spring web flow approach which is strictly tied down to spring views. I created a SPA using angular js with Spring MVC. In angular js I did not use routers or state, rather I created a div within the controller like below
<div width="100%" id="fullertonDataPanel" ng-include="page"></div>
On the server side to capture all possible transitions from one frame(I am referring to a particular screen in the SPA) to another I created a tree of rules using MVEL . So in the database I had a structure which stored a tree of rules for every frame . The data in the MVEL expressions were being set by the various services each action invoked. Thus on any action the following steps were followed.
1) Validate the action.
2) Invoke various services.
3) Capture the data from these services and merge it with the existing data of the user.
4) Feed this captured data into collection of rules for each frame along with the details of the current frame.
5) Run the rules of the tree w.r.t to current frame and fetch its output.
6) If there is only one transition then that is the final transition. If there are 2 transitions and one is default then ignore the default transition and use the other transition.
7) Return the template name of the transition to the angular controller and set the value of the page variable in the scope of the controller.
Using this approach all my services had to do was store data in different data fields w.r.t a particular action. All the complex if-else conditions for Web Flows or any complex process definitions(like the one defined in Spring-Web Flow) were not required. The MVEL rule engine managed all that and since it was all in the database it could be changed without needing a server re-start.
I believe this generic approach with MVEL is a flexible approach which comprehensively handles the problem of a convoluted flow without making the application code a mess or adding additional unnecessary xml files.
There is a new MVC framework and web flow implementation for Vaadin component model called Lexaden Web Flow
You can try it out for your application as possible alternative.
I'm going to write my first Java based web app, and I'm sort of lost how to begin.
Firstly, I would like a web app and a desktop app that do pretty much the same thing, without the hackish idea of embedding a web browser into the desktop app because that doesn't allow to easily make changes to the desktop without affecting the web app and vice versa.
Now, here my questions.
Right now, I have a bunch of POJOs and they communicate with a single class that, right now, uses a flat file as a "database", of course, in production, I would use a legitimate database and just change that single class. Is this a good idea? Will I be able to go from POJOs to a web app?
Should I use a framework? I would like to have this app written pretty soon, seeing that all the buisness logic is there, I just need to wrap it so its usable, so, I don't want to spend an extreme amount of time learning, say, Spring (which AFAIK is huge), but, I don't want to keep reinventing the wheel throughout my app either. I can always just use JSP and scriptlets...
If you said yes to the above, what framework(s) do you suggest? Please note that I would like a framework that I can start using in maybe 3-4 weeks of learning.
Will I have to start from scratch with the POJOs that I have written? They're well over 30k LOC, so, if it is like that, I'll be hesitant.
You will need:
a web framework. Since you have Swing background, JSF 2 will be your best bet (everything will be painful, of course, but JSF will get you up and going quickly and will help you avoid the most tragic mistakes). Also, wrapping business pojos into web guis is the main use-case for JSF and it's biggest focus.
a "glue framework". One thing that is much different with web applications as opposed to desktop ones is that you cannot create view components by yourself - they must be created when browser requests a page. So you have to find a way to create the view objects and deliver all the references to the pojos that represent logic, some of which may have very different lifecycles (this is not a problem on desktop, but on web you have to distinguish between pojos that live along with the whole application, along with a single user session, along with a single request, and so on).
The "glue framework" could also provide the additional benefit of managing transactions. You have three choices:
Spring. It's not half as complex as you thing; you only need to learn some basic stuff.
EJB. You would need a real application server, like Glassfish or JBoss
bare JSF has good support for dependency injection, the only drawback is the lack of automatic transaction management.
If I were in your position, I would go with bare JSF 2.0 - this way you only need to learn one new technology. At first, try to avoid libraries like PrimeFaces - they usually work worse than advertised.
edit - and addendum
or - what is "dependency injection"(abridged and simplified)
When request comes to a web application, a new task starts in a new thread (well, the thread is probably recycled, but that's not important).
The application has already been running for some time and most of the objects you are going to need are already built and should not get created again: you have your database connection pool, maybe some parts of business layer; it is also possible that the request is just one of many request made during one session, and you already have a bunch of POJOs that the user is working on. The question is - how to get references to those objects?
You could arrange your application so that resources are available through some static fields. They may be singletons themselves, or they could be acquired through a singleton locator. This tends to work, but is out of fashion (hard to test, hard to refactor, hard to reuse, lifecycles are hard coded in application). The real code could look like this:
public void doSomething() {
Customer Service cs = AppManager.getInstance().getCustomerService();
System.out.println(cs.getVersion());
}
if you need clustering and session management, you could build a special kind of broker that would know and provide to anyone all kinds of needed objects. Each type of object would be registered as a factory under a different name. This also works and is implemented in Java as JNDI. The actual client code would look like this:
public void doSomething() throws Exception {
CustomerService cs = (CustomerService)new InitialContext().lookup("some_fancy_looking_name_in_reality_just_string");
System.out.println(cs.getVersion());
}
The last way is the nicest. Since your initial object is not created by you but by the server just after http request arrives (details depend on the technology you choose, but your entry point might be a JSF managed bean or some kind of action controller), you can just advertise which references you need and let the server take care of finding them for you. This is called "Dependency Injection". Your acts as if everything is taken care of before your code is ever launched. Spring or EJB container, or CDI, or JSF take care of the rest. The code would look like this (just an example):
#EJB
CustomerService cs;
public void doSomething() {
System.out.println(cs.getVersion());
}
Note:
when you use DI, it really uses one of the two former methods under the hood. The good thing is: you do not have to know which one and in some cases you can even switch them without altering your code;
the exact means of registering components for injection differs from framework to framework. It might be a piece of Java code (like in Guice), an XML file (classic Spring) or an annotation (classic EJB 3). Most of the mentioned technologies support different kinds of configuration.
You should definitely use a framework as otherwise sooner or later you'll end up writing your own.
If you use maven then simply typing mvn archetype:generate will give you a huge list of frameworks to choose from and it'll set up all of the scaffolding for you so you can just play with a few frameworks until you find the one that works for you.
Spring has good documentation and is surprisingly easy to get started with. Don't be put off by the pages of documentation! You could use JPA to store stuff in the database. You should (in theory) just be able to annotate your existing POJO's to denote primary keys and so on and it should just work. You can also use JSP's within Spring if that makes life easier.
... I a bunch of POJOs and they communicate with a single class that, right now, uses a flat file as a "database", of course, in production, I would use a legitimate database and just change that single class. Is this a good idea? Will I be able to go from POJOs to a web app?
qualified yes. if the pojo's are sane you should not have many problems. many people use hiberbate.
Should I use a framework? I would like to have this app written pretty soon, seeing that all the buisness logic is there, I just need to wrap it so its usable, so, I don't want to spend an extreme amount of time learning, say, Spring (which AFAIK is huge), but, I don't want to keep reinventing the wheel throughout my app either. I can always just use JSP and scriptlets...
probably. spring is huge, but things like grails or roo can help.
if you want to have a responsive web app, you will need to do some kind of rich client (AJAX). this may require a lot of your code to run on the client. this means writing a lot of javascript or using gwt. this will be a pain. it probably will not be so easy to just "wrap it". if you have written a swing app, then basically that code will need to run on the client.
If you said yes to the above, what framework(s) do you suggest? Please note that I would like a framework that I can start using in maybe 3-4 weeks of learning.
i like groovy and grails - grails uses spring-mvc, spring, hibernate. but there is roo, play and others.
Will I have to start from scratch with the POJOs that I have written? They're well over 30k LOC, so, if it is like that, I'll be hesitant.
the code that will run on the server can probably be mostly left alone. the code that has to run on the client needs to be rewritten in javascript or maybe you can get some reuse out of that code by using gwt,
The Play Framework is doing great things. I would recommend it highly. Having worked with EJB apps and Tomcat/Servlet/Spring apps it's a breath of fresh air. After framework installation you get a working app in a few seconds. Reminds me of Ruby on Rails or Node.js with the type-safety of Java.
Much quicker turnaround on getting started, faster development cycles, and a clearer configuration model than previous Java web app frameworks.
http://www.playframework.com/
Usually, a user makes a search, get a hitlist, and can then browse it. The hitlist is an intermediate result that remains consistent throughout the browsing and is typically stored in session state. E.g. if new items are added concurrently by some other, they would appear only in a subsequent search.
In a REST application, I can't have this intermediate result easily -- neither does it belong to the client, nor the model. I have read Pagination in a REST web app, but am not completely clear with the answer. The solution there seems to assume that the model is not updated while the user browses the results.
We can of course imagine the world (the model) as series of immutable snapshot. By providing a timestamp (or a global version number), we then get a consistent view of the model at that time, which solves the problem from a conceptual point of view. It does however imply full versioning of the model. (I'm also wondering if there is a connection to draw with functional programming)
How should I deal with this issue?
Note: I'm asking because I plan to use the play framework, which has no notion of HTTP state or session at all; it's pure restful.
After you've got query result on the first search, You can save the result in a cache. For one server it can be ehcache (supported in play) or memcached (also supported by play) for a cluster environment. You can save the result by a static name + session id. So you only need session id for each request, it's saved in the client cookie and available in your play app.
You can use cached data for browsing pages. I'm also recommending ElasticSearch.
EDIT: A better way is you can use play-search http://github.com/jfp/play-search, Sample:
Query q = Search.search("object:dogs", Folder.class);
q.orderBy("object")
.page(2,5)
.reverse();
PS: Your decision with Play is perfect. I'm a professional .net developer and I can say the only (optimal) web framework in the world that can race with asp.net mvc 2 is Play framework. Grails is buggy, Django/Python, Yii/Php, Rails all are slow, not type safe and far from jvm/clr frameworks. wicket, tapestry, struts, jsf, spring mvc all are verbose and useless. spring roo is only a template generator. Asp.net mvc surpassed asp.net and became #1 development platform for .net, but sun worked for an old asp.net clone with jsf for next gen, big mistake. The only hope for java is play framework in my opinion. With scala module, it's perfect...
I'm kind of lost about what your context is, but if I have to provide a short answer, it is that search results should be part of the model. I assume you have a searchable model. What you do is index the parts you need to search and store the index info (making it part of the model, too). When you execute a search, you query the index and display results. Performing the search a second time would not contain newly added items, unless the index is regenerated.
This removes the need to use any session state and keeps it restful, as the indexing is just another operation performed on a resource. Is this what you need?