How should look configuration for multiple controllers in Spring MVC? - spring-mvc

I have 2 logical items News and Cars. For each of them I need to have separate controllers. How I should configure my application.

If youre using annotation based configuration, you can simply create 2 Classes that are annotated with #Controller, like:
package com.example.controllers;
#Controller
public class NewsController {
#RequestMapping(value = "/news")
public String handleNewsCall() {
...
}
}
and
package com.example.controllers;
#Controller
public class CarsController {
#RequestMapping(value = "/cars")
public String handleCarsCall() {
...
}
}
Don't forget to add the following lines to your spring xml if you use annotation based configuration.
<context:component-scan base-package="com.example" />
<mvc:annotation-driven />

Related

How do I inject an EJB in Spring MVC using annotations?

My dispatcher-servlet.xml has basically:
<context:component-scan base package="package.ejb" />
<mvc:annotation-driven />
In the #Controller class I have:
#Controller
public class ApplicationController {
#EJB(lookup="java:global/MyEarName/MyWebModuleName/BeanImplementation!package.ejb.morepackages.BeanImplementation")
private MyBeanInterface myBean;
This didn't work, it looks like Spring doesn't see the #EJB annotation and it gives an error at deploy time saying it doesn't find any Autowire candidate. So I added the following code:
#Autowired
#Qualifier("BeanImplementation")
public void setMyBean(MyBeanInterface myBean) {
this.myBean = myBean;
}
And on my bean implementation:
#Component("BeanImplementation")
#Stateless(mappedName = "BeanImplementation", name = "BeanImplementation")
#LocalBean
public class BeanImplementation implements MyBeanInterface {
It worked, but I need to use the lookup string of the EJB and I can't since Spring doesn't see #EJB. I was forced to revert to a non-Spring application to use #EJB(lookup="...").
So, to clarify the question: how do I inject an EJB in Spring MVC using annotations and using the EJB lookup string? Thanks.

Spring rest controller not returning html

I'm using spring boot 1.5.2 and my spring rest controller looks like this
#RestController
#RequestMapping("/")
public class HomeController {
#RequestMapping(method=RequestMethod.GET)
public String index() {
return "index";
}
}
when I go to http://localhost:8090/assessment/ it reaches my controller but doesn't return my index.html, which is in a maven project under src/main/resources or src/main/resources/static. If I go to this url http://localhost:8090/assessment/index.html, it returns my index.html. I looked at this tutorial https://spring.io/guides/gs/serving-web-content/ and they use thymeleaf. Do I have to use thymeleaf or something like it for my spring rest controller to return my view?
My application class looks like this
#SpringBootApplication
#ComponentScan(basePackages={"com.pkg.*"})
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
When I add the thymeleaf dependency to my classpath I get this error (500 response code)
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "index", template might not exist or might not be accessible by any of the configured Template Resolvers
I guess I do need thymeleaf? I'm going to try and configure it properly now.
It works after changing my controller method to return index.html like this
#RequestMapping(method=RequestMethod.GET)
public String index() {
return "index.html";
}
I think thymeleaf or software like it allows you to leave off the file extension, not sure though.
RestController annotation returns the json from the method not HTML or JSP. It is the combination of #Controller and #ResponseBody in one. The main purpose of #RestController is to create RESTful web services. For returning html or jsp, simply annotated the controller class with #Controller.
Your example would be something like this:
Your Controller Method with your route "assessment"
#Controller
public class HomeController {
#GetMapping("/assessment")
public String index() {
return "index";
}
}
Your Thymeleaf template in "src/main/resources/templates/index.html"
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p>Hello World!</p>
</body>
</html>
I solved this by removing #EnableWebMvc annotation from configuration class.
Spring MVC Auto-configuration provides static index.html support.
If you want to take complete control of Spring MVC, you can add your
own #Configuration annotated with #EnableWebMvc.
Get more detail from Spring MVC Auto-configuration.
If you try to "Building a RESTful Web Service" -> annotate your controller class with #RestController annotation if not annotate your controller class with #Controller class.
When we use spring as SpringMVC - #Controller
When we use spring as SpringRESTfull Web Service - #RestController
Use this link to read : Spring Stereo Type

How to write 2 controllers in spring MVC

Is it possible that spring MVC contain 2 controllers like DispatherServet write more than one time
when we developing spring MVC applications.
Yes..!! It is Possible.
You have to set a #RequestMapping annotation at the class level the value of that annotation will be the prefix of all requests coming to that controller.
Example:
For 1st Controller :
#Controller
#RequestMapping("test")
public class TestController {
}
For 2nd Controller :
#Controller
#RequestMapping("demo")
public class DemoController {
}
If both the controller have the same/different methods you can access like this
<your server>/test/<RequestMappingName of Method>
<your server>/demo/<RequestMappingName of Method>

Ambiguous mapping found when using class multi level #RequestMapping urls

I'm getting the following exception if I use multi level urls in class like #RequestMapping("/api/v0.1"):
java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'userController'
bean method getUsers()|to {[/api/v0.1]}: There is already 'userController' bean
method getUser(java.lang.String) mapped.
It's like the method level mappings doesn't get into consideration at all.
But it's ok if I put #RequestMapping("/api") i.e. remove the /v0.1 part.
Here is the configuration stripped up to the minimal case:
#Controller
#RequestMapping("/api/v0.1")
public class UserController {
#RequestMapping(value = "/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
web.xml
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet-context.xml:
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="home"/>
<!-- Handles HTTP GET requests for /assets/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/assets/**" location="/assets/" />
I'm using spring 3.1. I also tried to set alwaysUseFullPath property to true of the RequestMappingHandlerMapping bean but it didn't change the situation.
Very interesting issue - I checked what could be going on, you are right the "v0.1" is really throwing off the org.springframework.util.AntPathMatcher which creates the full URI path by combining the path from the controller and the path from the mapped method. If it sees a "file.extension" kind of a pattern in the Controller, then it totally ignores the path mapping of the method - this is the reason why your #PathVariable was getting ignored.
I am not sure if this is a bug or intended behavior in Spring MVC, temporary fix would be along what you have already mentioned -
1.To remove "v0.1" from the RequestMapping of Controller and make it without extension say v0_1
2.To put this mapping in the mapped method:
#Controller
#RequestMapping("/api")
public class UserController {
#RequestMapping(value = "/v0.1/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/v0.1/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
You should use the #RequestMapping(value = "/{version:.*}/users") to include the dot '.' in the path variable

gwt-gwt 3.0 file upload issue with Spring MVC

I'm having a problem getting the file object when I use FormPanel, FileUploadField, and Spring.
Here is what I have:
I added the CommonsMultipartResolver bean to my Spring Context file:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000"/>
</bean>
I have a model class with the regular getters and setters:
pulic class UploadItem{
private String filename;
private CommonsMultipartFile fileData;
....
getters/setters
....
}
My controller class:
#Controller
#RequestMapping("/Foo")
public class ThingController extends BaseController implements ServlerContextAware{
....
#RequestMapping(value = "/bar", method = RequestMethod.POST)
public #ResponseBody
String createFile(UploadItem item, BindingResults results){
String orgFile = item.getFileData().getOriginalFilename();
return orgFile;
}
I'm using UiBinding to create the form fields, but I'm calling the fileupload field and formpanel to add the other methods in code.
I have a submit button that calls:
form.submit();
And my constructor I take care of the other form requirements:
form.setMethod(Method.POST);
form.setEncoding(Encoding.MULTIPART);
form.setAction("http://url.com/foo/bar");
form.addSubmitCompleteHandler(new SubmitCompleteHandler(){
#Override
public void onSubmitComplete(SubmitCompleteEvent event){
String results = event.getResults();
Info.display("Upload Response", results);
}
});
When I run the code I get a nullpointerexecption on item.getFileData().getOriginalFilename();
I don't know what the problem is.
My guess is the form isn't bound to the UploadItem, because you never told Spring to do that. Now, I am hoping that someone knows how to do this. Normally I would use Spring's form tag library and provide a modelAttribute or commandName in the form, but since I (and the ts) use GWT the form is built from GWT components and I can't use Spring form tags.

Resources