I am using SpringMVC 3 with Annotated Controllers. I successfully mapped my URL ("/HelloWorld) to a Controller and defined its GET processing method.
The error is that upon typing the (App)/HelloWorld URL, my web server (GlassFish) gives this error:
The requested resource is not available.
But in the GlassFish log I see that the URL was mounted.
Mapped "{[/HelloWorld],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView controllers.HelloWorldController.processHelloWorld()
My Files:
(1) HelloWorldController.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
*
* #author */
#Controller
#RequestMapping("/HelloWorld")
public class HelloWorldController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView processHelloWorld()
{
ModelAndView model = new ModelAndView("HelloWorldPage");
model.addObject("msg", "Expanded string - hello world");
return model;
}
}
(2) Dispatcher-Servlet.xml. Note the MVC-Annotation-Driven approach. The indexController is not used.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="controllers" />
<mvc:annotation-driven />
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
(3) HelloWorldPage.jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h1>Spring MVC Hello World Annotation Example</h1>
<h2>${msg}</h2>
</body>
</html>
Any ideas why the URL "/HelloWorld" is not being found? Thanks.
Problem solved. I had to invoke the URL "/HelloWorld.htm" for the mapping to work.
(The Dispatcher-Servlet's mapping in web.xml is "*.htm".) Thanks
Related
I hope someone can help me, I am starting to work with Spring MVC.
I have a java spring MVC web application with this packages: com.app.controller, com.app.modelo, com.app.servicio, y com.app.repositorio. In the repositorio package I have the UsuarioRepositorio interface, in the servicio package I have the UsuarioServicio class. The controller uses the UsuarioServicio class and this one uses de UsuarioRepositorio interface. The controller initializes the UsuarioServicio object in it´s constructor. When running the project it shows this error:
The module has not been deployed.
See the server log for details.
[Payara 5.2021.10] [GRAVE] [] [javax.enterprise.system.core] [tid: _ThreadID=90 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1643303084394] [levelValue: 1000] [[
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchMethodException: com.app.controller.UsuarioController.()]]
UsuarioRepositorio interface
package com.app.repositorio;
import com.app.modelo.UsuarioModelo;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UsuarioRepositorio extends JpaRepository<UsuarioModelo, Integer>{
Optional<UsuarioModelo> porUsuario(String CodigoUsuario);
Optional<UsuarioModelo> porUsarioEstatus(String CodigoUsuario, boolean EstatusLogeado);
Optional<UsuarioModelo> porUsuarioIntentos(String CodigoUsuario, int CantidadIntentos);
}
UsuarioServicio class
package com.app.servicio;
import com.app.modelo.UsuarioModelo;
import com.app.repositorio.UsuarioRepositorio;
import org.springframework.stereotype.Service;
#Service
public class UsuarioServicio {
private final UsuarioRepositorio repouser;
public UsuarioServicio(UsuarioRepositorio ru){
repouser = ru;
}
public UsuarioModelo registrarUsuario (String usuario){
if (usuario == null){
return null;
}else{
UsuarioModelo usermodel = new UsuarioModelo();
usermodel.setCodigoUsuario(usuario);
return repouser.save(usermodel);
}
}
public UsuarioModelo autentica(String usuario){
return repouser.porUsuario(usuario).orElse(null);
}
}
Controller
package com.app.controller;
import com.app.modelo.UsuarioModelo;
import com.app.servicio.UsuarioServicio;
import com.app.repositorio.UsuarioRepositorio;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class UsuarioController {
private UsuarioServicio userserv;
public UsuarioController(UsuarioServicio us){
userserv = us;
}
#GetMapping("/index")
public String getLoginPage(Model modelo) {
modelo.addAttribute("loginrequest", new UsuarioModelo());
return "index";
}
#PostMapping("/index")
public String login(#ModelAttribute UsuarioModelo usermod){
UsuarioModelo logeduser = userserv.autentica(usermod.getCodigoUsuario());
logeduser = logeduser == null ? userserv.registrarUsuario(usermod.getCodigoUsuario()) : logeduser;
return logeduser == null ? "error_page" : "redirect:/index";
}
}
I think the error could be due to a misconfiguration of the dispatcher-servlet.xml file because I remove the UsuarioServicio from the controller and the application runs perfectly
dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">UsuarioController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />-->
<bean name="UsuarioController" class="com.app.controller.UsuarioController"/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
applicationContext.xml
<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" /-->
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->
</beans>
application.properties
spring.datasource.url=jdbc:sqlserver://XXXXXX;databaseName=XXXXX
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.username=XXXXXX
spring.datasource.password=XXXXXX
spring.jpa.properties.hibernate.dialeg = org.hibernate.dialect.sqlserver
I modified the dispatcher-servlet like this:
<bean name="UsuarioController"
class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio"
value="us"/>
</bean>
Now the error is this:
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'UsuarioController' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [com.app.servicio.UsuarioServicio]: Failed to convert value of type 'java.lang.String' to required type 'com.app.servicio.UsuarioServicio'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.app.servicio.UsuarioServicio': no matching editors or conversion strategy found]]
I have updated the dispatcher-servlet.xml file like this
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us"/>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
and like this
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us"/>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="UsuarioServicio" />
</bean>
Both cases the error is noew this
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchMethodException: com.app.servicio.UsuarioServicio.()]]
I modified the dispatcher-servlet like this:
<jpa:repositories base-package="com.app.repositorio"/>
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us">
<constructor-arg ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
And I got this error
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.xml.sax.SAXParseException; lineNumber: 36; columnNumber: 59; El prefijo "jpa" para el elemento "jpa:repositories" no está enlazado.]]
Then I removed de prefix "jap" like this
<repositories base-package="com.app.repositorio"/>
<bean name="UsuarioServicio" class="com.app.servicio.UsuarioServicio" id="us">
<constructor-arg ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg type="com.app.servicio.UsuarioServicio" ref="UsuarioServicio" />
</bean>
and the error is this
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.xml.sax.SAXParseException; lineNumber: 36; columnNumber: 55; cvc-complex-type.2.4.a: Se ha encontrado contenido no válido a partir del elemento 'repositories'. Se esperaba uno de '{"http://www.springframework.org/schema/beans":import, "http://www.springframework.org/schema/beans":alias, "http://www.springframework.org/schema/beans":bean, WC[##other:"http://www.springframework.org/schema/beans"], "http://www.springframework.org/schema/beans":beans}'.]]
I did some research and found some configurations to do in the dispatcher-servlet
dispatcher-servle.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa-2.6.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-5.3.xsd" >
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<mvc:annotation-driven conversion-service="UsuarioServicio"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">UsuarioController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />-->
<context:component-scan base-package="com.app.repositorio" />
<jpa:repositories base-package="com.app.repositorio"/>
<bean id="UsuarioRepositorio" class="com.app.servicio.UsuarioServicio" >
</bean>
<bean id="UsuarioServicio" class="com.app.servicio.UsuarioServicio">
<constructor-arg name="ur" ref="UsuarioRepositorio"/>
</bean>
<bean name="UsuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="UsuarioServicio"/>
</bean>
</beans>
now the error seems to be with this line <context:component-scan base-package="com.app.repositorio" />
org.xml.sax.SAXParseException; lineNumber: 46; columnNumber: 54; cvc-complex-type.2.4.c: El comodín coincidente es estricto, pero no se ha encontrado ninguna declaración para el elemento 'context:component-scan'.
I added this line #ComponentScan(basePackages = { "com.app.repositorio" }) to the UsuarioRepositorio interface, now the file is this
UsuarioRepositorio interface
package com.app.repositorio;
import com.app.modelo.UsuarioModelo;
import java.util.Optional;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
#ComponentScan(basePackages = { "com.app.repositorio" })
public interface UsuarioRepositorio extends JpaRepository<UsuarioModelo, Integer>{
Optional<UsuarioModelo> porUsuario(String CodigoUsuario);
Optional<UsuarioModelo> porUsarioEstatus(String CodigoUsuario, boolean EstatusLogeado);
Optional<UsuarioModelo> porUsuarioIntentos(String CodigoUsuario, int CantidadIntentos);
}
Corrections
The below corrections are ordered from lower level layers to higher level ones.
Correction #1: Persistence layer: Activate the Spring Data JPA repository bean support
Add the jpa XML namespace:
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
Update the xsi:schemaLocation XML schema location by adding the following:
http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa.xsd
Then add the repositories element:
<jpa:repositories base-package="com.app.repositorio" />
As a result:
Each bean is registered under a bean name that is derived from the interface name, so an interface of UserRepository would be registered under userRepository.
— Spring Data JPA - Reference Documentation.
Therefore, this should provide the usuarioRepositorio bean for our case.
For more details and a complete example, please, see the page: Spring Data JPA - Reference Documentation.
Correction #2: Application service layer: Add UsuarioServicio bean
Use the reference to the usuarioRepositorio bean for the usuarioServicio bean.
<bean id="usuarioServicio" class="com.app.servicio.UsuarioServicio">
<constructor-arg ref="usuarioRepositorio" />
</bean>
Please, note the case used for the id and ref attribute values: usuarioServicio, usuarioRepositorio.
Correction #3: Integration layer: Update UsuarioController bean
Use the reference to the usuarioServicio bean for the usuarioController bean.
<bean id="usuarioController" class="com.app.controller.UsuarioController">
<constructor-arg ref="usuarioServicio" />`
</bean>
Please, note the case used for the id and ref attribute values: usuarioController, usuarioServicio.
I'm a beginner to spring-mvc. I was trying to create a login page using spring-mvc. But my controller is not invoked on submit button. I get the 404 error.
login.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout/default">
<head lang="en">
<title>User Login</title>
</head>
<body>
<form method="POST" action="/SpringApplication/postLogin" >
<table>
<tr><td>User Name: </td><td><input name="userName" type="textbox"></td></tr>
<tr><td>Password: </td><td><input name="password" type="password"></td></tr>
<tr><td colspan="2" align="right"><input type="submit" value="Submit"></td></tr>
</table>
<div style="color:red">${error}</div>
</form>
</body>
</html>
LoginController.java
package core.controllers;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class LoginController {
#RequestMapping(value = "/SpringApplication/postLogin", method = RequestMethod.POST)
public String postSearch(HttpServletRequest request, Model model) {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
if (userName.isEmpty() || password.isEmpty()) {
model.addAttribute("error", "Please enter some value!");
return "redirect:/";
}
model.addAttribute("msg", "success");
return "resultPage";
}
}
dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?xml version="1.0" encoding="UTF-8"?> -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="login.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="login" />
</beans>
Project Structure
You have a wrong action property on your form .
Controller is waiting for a "/SpringApplication/postLogin" request, and the form is submitting to "/SpringApplication/postSearch".
Your button's action is
action="/SpringApplication/postSearch"
while your controller maps
value = "/SpringApplication/postLogin"
Try to change your controller's mapping to
value = "/SpringApplication/postSearch"
edit: you seem to have fixed above issue. But your controller wants to return a jsp file called "resultPage" which is nowhere to be found in your jsp folder.
I 'm using Spring 3.0.1.RELEASE for my webapp (and i have no way for upgrading it) and i'm trying to render some images from database on web-page.
I have following simple Spring configs:
spring-application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<task:annotation-driven />
<context:annotation-config />
<context:spring-configured />
<context:component-scan base-package="com.me" />
<bean id="hibernateSessionFactory" class="com.me.dbaccess.HibernateSessionFactory">
<constructor-arg ref="sessionFactory"/>
</bean>
</beans>
spring-mvc.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<bean id="tilesViewResolver" class="com.me.util.TilesExposingBeansViewResolver">
<property name="viewClass" value="com.me.util.TilesExposingBeansView"/>
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/config/tiles-defs.xml</value>
</list>
</property>
</bean>
</beans>
I have following controller:
#Controller
public class PhotoController {
#RequestMapping("/carPhoto.html")
#ResponseBody
public byte[] getCarPhoto(
#RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
#RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
//return image's bytes array from db by photo Id and Type;
}
}
And finally, I have simple jsp-page:
<%#page contentType="text/html; charset=utf-8"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<img id="photoImage" src="<c:url value="/carPhoto.html?photoType=1&photoId=22556793"/>" />
If I open this page - I can see this image without any problems.
But if I copy image "src" attribute and paste it in browser's address bar (Firefox 19.0.2) - then browser offers me to save carPhoto.html, instead of just render the image.
Should I perform some additional setup?
The problem is, that you have to specify the mime type (and if your image is larger you will need to specify its length too).
An other solution () is to return a Spring ResponseEntity or HttpEntity (HttpEntity is enough if you always return http status code 200, ResponseEntity (a subclass of HttpEntity) is for example needed if you want to return other http status codes, like not found).
#Controller
public class PhotoController {
#RequestMapping("/carPhoto.html")
#ResponseBody
public HttpEntity<byte[]> getCarPhoto(
#RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
#RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
byte[] image = image's bytes array from db by photo Id and Type;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG); //or what ever type it is
headers.setContentLength(image.length);
return new HttpEntity<byte[]>(image, headers);
}
}
There are several ways. Easiest is to use #ResponseBody with a byte[] as your return type, set your Content-Type and such, the write the bytes to the output stream using the HttpServletResponse.
A more elegant solution (IMO) would be to return a ModelAndView, then set the View on that to a custom view that sets the proper headers (Content-Type and such) and writes out the bytes to the HttpServletResponse's output stream.
I'm trying to learn spring MVC, so far so good but I'm kind of stuck now. I'm trying to learn how to create json and get it with javascript(jquery).
But for testing purposes I tried to create something just so I can see that is displayed properly trough http request, then I'll try to create json and get it, but so far I can't even get the request to work. Here is my controller :
#Controller
#RequestMapping(value="/")
public class IndexController {
#RequestMapping(method=RequestMethod.GET)
public String index() {
return "index";
}
Map<Long,Item> itemMap = createItemMap();
#RequestMapping(value="item/{itemId}", method=RequestMethod.GET)
public #ResponseBody Item get(#PathVariable Long itemId) {
Item item = itemMap.get(itemId);
if (status == null) {
throw new ResourceNotFoundException(itemId);
}
return item;
}
private Map<Long,Item> createItemMap(){
//omitted because its irrelevant
//I created 2 item objects , with id 1 and 2 for testing purposes
}
}
This is content of my servlet-context.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- Imports user-defined #Controller beans that process client requests -->
<beans:import resource="controllers.xml" />
</beans:beans>
And controllers.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Scans within the base package of the application for #Components to configure as beans -->
<context:component-scan base-package="com.testing.mvc.controller" />
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages" />
<property name="cacheSeconds" value="0" />
</bean>
</beans>
My war is called Test.war, when I try localhost:8080/Test I get index view which is OK. But regardless of what I try:
localhost:8080/Test/item/1
localhost:8080/Test/item?itemId=1
localhost:8080/item?itemId=1
I end up with some kind of error, the most interesting is this one :
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().
I've googled alot found these to be interesting :
http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
https://src.springframework.org/svn/spring-samples/mvc-ajax/trunk/
Mapping restful ajax requests to spring
Spring's Json not being resolved with appropriate response
Nothing helped so far, any idea what I'm missing. Sorry for providing too much info.
As far as I can tell you are missing this resolver like this in your dispatcher serlet:
<bean name="jsonViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="1"/>
</bean>
Take look at this:
http://spring-json.sourceforge.net/quick_simpleform.html
You have to create file views.xml in yoru WEB-INF direcotry with this content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/>
</beans>
I'm somewhat new to Spring (using 3.0), so I'm hoping there is a simple answer. If I have a controller that is annotated with #Controller and #RequestMapping and I want to set a property via dependency injection, how do I go about doing that? The controller class doesn't have to appear in the Spring configuration file because it gets picked up automatically because of the #Controller annotation.
Example Controller class:
package gov.wi.dnr.wh.web.spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class RehabHomeController {
private String xxx;
#RequestMapping(value="/rehab/home", method = RequestMethod.GET)
public String get() {
return "whdb.rehabhome";
}
public String getXxx() {
return xxx;
}
public void setXxx(String xxx) {
this.xxx = xxx;
}
}
Spring configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<context:component-scan base-package="gov.wi.dnr.wh.web.spring"/>
<mvc:annotation-driven />
</beans>
This works as is, but I would like to inject the "xxx" property. How do I go about doing that?
#Autowired
private YourService yourServiceBean;
(you can also use #Inject)
Of course, YourService has to be declared as a bean - either in applicationContext.xml, or by annotations (#Service for example)
If you want to inject string properties, you can use the #Value annotation:
#Value("${propName}")
private String str;
(For that you will need a PropertyPlaceholderConfigurer)