I am using Spring Portlet MVC and Websphere Portal for my portlet application. In my jsp:
<portlet:actionURL var="saveFinishUrl">
<portlet:param name="action" value="saveFinish" />
</portlet:actionURL>
Now, I have a controller class defined in my portlet.xml. In that class, I have a method called saveFinish annotated like this:
#ActionMapping(params = "action=saveFinish")
My question is that in the jsp there should be a mapping that maps the jsp to tejh controller class. Otherwise how does the portlet container know which controller class is supposed to handle the request?
I know that <portlet:actionURL will generate a url that will direct to the correct controller...but how?
Your jsp in portlet environment is served by a particular portlet.
In case of spring mvc the first jsp is decided by the controller that has a #RenderMapping for view mode.
Also you know that you can use the action attribute of potlet:actionURL tag to set the action, and then use it as a value of #ActionMapping annotation?
Related
I know that MVC is a design pattern that separates Model, View, Controller.
Model - Logic
View - Client View
Controller - connection between the two.
In case I want to change one of this things it will be easy just to change view\Model and the controller.
So is it possible to use only WebApi and MVC without Aps.Net pages (cshtml files)?
You can return html files
return new FilePathResult("path/FileName.html", "text/html");
And .cshtml files are Razor View Engine files, not Asp.Net pages.
You can alson change the view engine, see here for a list of .net view egines.
In short: yes, you can.
To elaborate: not sure what you mean, as .cshtml files are essentially the view part of MVC (the V part). ASP.NET MVC controllers by default return content of the .cshtml file by calling View() helper method.
But you can for example render html for the client inside your custom controller class without calling for a static html content. Or you might create WEB API project, with routing, models, and controllers, but no views - just plain data returned to the client.
I'm using Spring MVC through Spring boot starters (1.3.2) and i saw a difference of behavior regarding which template engine i'm using.
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
// template file
registry.addViewController("/index").setViewName("index");
// static file
registry.addViewController("/login").setViewName("login.html");
}
}
If i used Freemarker as template engine, Spring mvc will take the file from resources/static for /login and in resources/templates for /index
Whereas, if i used Thymeleaf as template engine, Spring will take all the files (login and index) from resources/templates.
As far as I know, this paths depends of application properties. By default:
#for freemaker
spring.freemarker.template-loader-path=classpath:/templates/
#for thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
Full list of common application properties you can find here.
View controller does not change behavior. When you entered url, Spring looking for method of Controller or ViewController, which has suitable request mapping. If method found, Spring invoke it. After that, controller's method returns view name as string, and Spring ask for special bean, named ViewResolver, to find view with this name.
Since every template engine has own ViewResolver, and any ViewResolver has it's own setings (as I said above), they're looking for templates in different places.
For example, you're using Thymeleaf and entered as url something like: localhost:8080/index. First, spring will find controller method or view-controller mapped with index. After that, controller will return string index. Spring will ask for Teamleaf view resolver to find this view. According to default settings, view resolver will add classpath:/templates/ before view name, and .html after view name, and after that will try to open file with this name.
Which Authorize Attribute ?
System.Web.Http.Authorize
System.Web.Mvc.Authorize
using System.Web.Mvc // or
using System.Web.Http
A typical controller
[Authorize]
public class SomeController : Controller
We have controllers Annotated with [Authorize]
I just noticed that due to using namespaces the annotations technically refer to different attribute classes.
The project contains MVC controllers and WEBAPI controllers.
Which one should I use and why ?
What issues might we have if I dont fix this ?
You must use System.Web.Http.Authorize against an ApiController (Web API controller) and System.Web.Mvc.Authorize against a Controller (MVC controller). Since the framework runs the filters as part of the pipeline processing and the controllers expect the right filter to be applied, if you don't use the corresponding filter, authorization will not work.
I've just started to use the VS 2012 RC, and I'm creating an ASP.NET MVC 4 web application in which I plan to provide both an HTML-based user interface and a WebApi-based programming interface.
For my HTML website, I have a controller and view for each of my models (MVC!), and the routing works "by convention" so that, for example, the URL /client hooks up to my ClientController. My ClientController derives from Controller.
For my API, I will create new controllers that derive from ApiController. I naturally want my API URLs to be similar to my HTML URLs, so I'd like the client info to be available at /api/client. However, with the by-convention routing, that would suggest that I need an ApiController named ClientController. And I already have a ClientController class.
How do I deal with this? Do I need custom routing? Do I put the API classes in different namespace so that I can give them the same name?
Update: this question seems to suggest that a different namespace for my API controllers is all I need: Mix web api controllers and site controllers
All it requires is for the controller classes to be in a different namespace, and all is well.
Using MVC areas would also work (as suggested in gordonml's comment), but this effectively puts the controllers in different namespaces, so it's a more formal way of achieving the same result.
You may take a look at the following blog post which illustrates how an Api controller could serve Razor views as well. Basically he uses the RazorEngine to parse the Razor view end serve it.
For anyone looking for step by step guidance on how to do this on WebApi project:
Create two folders / namespaces, namely: ControllersApi and ControllersWeb
Right click on ControllersWeb and go Add -> Controller and select MVC 5 Controller - Empty. This will add all other dependencies if you didn't have them in your WebApi project.
Your RouteConfig will now register those classes that inherit from Controller base class. You'll likely need to add link to default Controller, by editing defaults to say: defaults: new { action = "Index", controller = "Home", id = UrlParameter.Optional }
That's it, you can now run site and use both API and Web controllers.
I have following app setup.
The dispatcher servlet is matched to the *.htm URL pattern.
Controller has the annotation #RequestMapping(value = "doSuccess")
The method for the above annotation just returns new ModelAndView("success");
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp"
p:order="1"/>
The index page has the link
Click me
There is a file called success.jsp located in /WEB-INF/jsp/
Now, when I click on the Click me, I get a 404. I did a bit of debugging and realized that the method in the controller was indeed being called but irrespective of the return statement it is trying to find doSuccess.htm.
I figured the error. I was using Netbeans and i used the auto complete imports. It was importing the org.springframework.web.portlet.ModelAndView instead of servlet.ModelAndView.