Spring Extension REST Resource #RequestParam annotation not detected - model-view-controller

trying to use the spring extension of Restlet ,
have configured as per the example http://wiki.restlet.org/docs_2.1/13-restlet/28-restlet/70-restlet/196-restlet.html
In addition to that trying to capture the request parameters using the #RequestParam annotation but end up getting the parameter value as null.
Resource looks like,
class MyResource extends ServerResource implements IResource {
#Get
#RequestMapping(value="/id")
public void get(#RequestParam(value="name") String name) {
...
}
}
HTTP Request http://localhost:8080/messages/id?name=XXX
Web.xml looks like
<servlet>
<servlet-name>test-servlet</servlet-name>
<servlet-class>org.restlet.ext.spring.RestletFrameworkServlet</servlet-class>
</servlet>
<!-- Catch all requests -->
<servlet-mapping>
<servlet-name>test-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
In the end the name value is 'null'. I think the spring based annotations are not detected. I have no clue why this is happening?

Related

throwing NoHandlerFoundException and configuring custom 404 page in SpringBoot

I have been learning Spring for just 7 months. While I used spring MVC only, i want to configure custom 404 page by throwing NoHandlerFoundException or enabling it in the dispatcher servlet. Now, i am learning spring boot, can anyone explain to me?
I had the same issue, got it resolved. Below given steps to solve the same.
Create a class GlobalExceptionHandler annotated with #ControllerAdvice
#ControllerAdvice
public class GlobalExceptionHandler
{
#ExceptionHandler(NoHandlerFoundException.class)
public String handleNotFoundError(Exception ex)
{
return "redirect:/yourCustom404page";
}
}
By default, when a page/resource does not exist the servlet container will render a default 404 page. If you want a custom 404 response then you need to tell DispatcherServlet to throw the exception if no handler is found. We can do this by setting the throwExceptionIfNoHandlerFound servlet initialization parameter to true
to achieve this
a. In spring-boot
spring.resources.add-mappings=false in your application.properties or yaml file.
b. If spring-mvc java based configuration is
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
...
#Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext)
{
final DispatcherServlet servlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
servlet.setThrowExceptionIfNoHandlerFound(true);
return servlet;
}
}
c. if spring-mvc xml based configuration, initialize your dispatcher servlet like this
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

Spring unit test 404\unknown url in mock mvc

I would like to test that when an unknown url is requested and a 404 error is generated that my web app actually redirects to the right place.
I havent been able to get this working, I think because tomcat is handling the 404 errors so the forwardedUrl is always null for the tests. I know this works in reality because if I enter some rubbish into the url my app does redirect to my custom page.
My unit test looks like:
#Test
public void testUnknownUrl() throws Exception {
mockMvc.perform(get("/url_doesnt_exist"))
.andExpect(status().isNotFound())
.andExpect(forwardedUrl("/static/error/Sorry.html"));
}
My web.xml configuration is:
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/static/error/Sorry.html</location>
</error-page>
The mapping for /static is defined in my spring config like:
<resources mapping="/static/**" location="/resources/" />
Ultimately I would like to mock a request to an unknown url and then check that the page being returned is /static/error/Sorry.html.
Am I doing something wrong or is this not the way to handle 404 etc in spring? The check of the forwarded url in the unit test is always null.
A slightly different question but related all the same is, at what point does the tomcat error handling get invoked over and above the spring controller advice handling?
I'm not sure about the configuration with the /static path in your web.xml, it shouldn't be like that depending on your dispatcher-servlet (default name) configuration; but as far as I can tell you are in the right path.
This is what I have for mine:
#WebAppConfiguration
#ActiveProfiles("development")
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = AppConfig.class)
public class ErrorControllerTest {
#Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context)/*.alwaysExpect(status().isOk())*/.build();
}
#Test
public void testError() throws Exception {
mockMvc.perform(get("/error").contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk()) // See "alwaysExpect" above
.andExpect(view().name("error"))
.andExpect(forwardedUrl("/WEB-INF/views/error.jsp"));
}
#Test
public void testResourceNotFound() throws Exception {
mockMvc.perform(get("/resource-not-found").contentType(MediaType.TEXT_HTML))
.andExpect(status().isNotFound())
.andExpect(view().name("resource-not-found"))
.andExpect(forwardedUrl("/WEB-INF/views/resource-not-found.jsp"));
}
}
Sample project is here. I'm using JSPs but you can switch to .html just by changing the InternalResourceViewResolver configuration.
I am using spring 3 and after some reading around I have found out the dispatcher servlet just returns a response code without throwing an exception which I guess is why tomcat always handles this.
Removing the error page tags from web.xml results in a tomcat generic 404 page, so I think the answer to this is to upgrade to spring 4 where I can then pass an init param to the dispatcher servlet requesting it throw an error for a page not found.
I am happy to be corrected on this though as it may help my understanding.

jersey 2.5 and Spring 2.5 integration not working

I am trying to integrate Jersey (Version 2.x) into our current project which use's Spring 2.5. I have followed all the steps mentioned in their Spring webapp integration sample, but can't seem to get the auto wiring to work when the Jersey bean is called.
My config/class files are given below,
WEB.XML FILE
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.inrev.rest.XXXSpringIntegration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
SPRING FILE
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean name="myresource" class="com.xxx.rest.MyResource" autowire="byName"></bean>
XXXSpringIntegration CLASS
public XXXSpringIntegration()
{
register(RequestContextFilter.class);
register(MyResource.class);
System.err.println("I am getting registered");
}
MyResource.class
#Path("myresource")
public class MyResource {
#Autowired
private IRAdminDAO adminDAO;
public MyResource()
{
System.err.println("Getting ready now");
}
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#Path("/list")
#GET
#Produces("application/json")
public String list()
{
System.err.println("Adming DAO "+adminDAO);
return "Got it!";
}
public void setAdminDAO(IRAdminDAO adminDAO)
{
System.err.println("Adming dao being set "+adminDAO);
this.adminDAO = adminDAO;
}
}
Added configuration for adminDAO
<bean id="adminDAO" class="com.xxx.bm.dao.impl.IRAdminDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
I am sure that the auto wiring works when Spring get's initialised, as the Syserr in the setter get's called when the file get's initialised by spring. However, when I make the API call, the adminDAO is null.
http://bm.com:8080/bm/rest/myresource/list
What could be causing this, I have tried all other permutation combinations but somehow the autowiring doesn't seem to be working when we make the API call.
Regards
Jersey work's fine with Spring 2.5, it's just a few jar's which were not present in my build. I am not sure if they would come with the maven build, but are certainly not present in the .zip download.
Also, there is no exceptions suggesting the jar is missing. jersey-spring3-2.11.jar being the star.

Spring request mapping: Matching with url pattern

I have a web application with Spring MVC.
web.xml
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/companies/*</url-pattern>
</servlet-mapping>
spring controller method:
class RealmInfoController{
#ResponseBody
#RequestMapping(value = {"/companies/{companyId}/realms/{realmName}"})
public RealmInfo realmInfo(#PathVariable long companyId, #PathVariable String realmName)
Handler match:
http://localhost:6122/context/companies/15877/realms/firstRealm
When the server gets this url, the spring servlet gets called. but it cannot match the controller method.
But if I change the request mapping to "/{companyId}/realms/{realmName}" then it matches the controller method. But it is not nice to define the url mapping without '/companies'. Can Spring be instructed in some way to look for match including the url pattern specified in the servlet?
Thanks.
if you want to use "companies" in request mapping you should map your dispatcher servlet to the root:
<url-pattern>/*</url-pattern>

Servlet Mapping Help - Possible to Avoid Referencing Context Name?

I am working on a Spring application using Tomcat 6 and Spring 2.5. I'm trying to get my URL mapping correct. What I would like to have work is the following:
http://localhost:8080/idptest -> doesn't work
But instead, I have to reference the context name in my URL in order to resolve the mapping:
http://localhost:8080/<context_name>/idptest -> works
How can I avoid the requirement of referencing the context name in my URL without using a rewrite/proxy engine e.g. Apache?
Here is the servlet definition and mapping from my web.xml:
<servlet>
<servlet-name>idptest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/idptest.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>idptest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Here's the outline of my controller (showing annotations for request mappings):
#Controller
#RequestMapping("/idptest")
public class MyController {
#RequestMapping(method=RequestMethod.GET)
public String setupForm(Model model){
MyObject someObject = new MyObject();
model.addAttribute("someObject", someObject);
return "myform";
}
#RequestMapping(method = RequestMethod.POST)
public String processSubmit(#ModelAttribute("someObject") MyObject someObject) throws Exception {
// POST logic...
}
}
Thanks!
That's going to depend on your servlet container, for Tomcat - you pretty much have to deploy your webapp as the ROOT webapp, that is, under $CATALINA_HOME/webapps/ROOT/
More info here
Just rename your war file to ROOT.war, then the application runs in root context (i.e. with empty context name)

Resources