I need to add a watermark to an image added to folder (space) "Images in" and move the image to the space "Images out" (via content rule).
The transformer (added to c:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\com\xyz\:
package com.xyz;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.repo.content.transform.AbstractContentTransformer2;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
* User: dragan
*/
public class ImageTransformer extends AbstractContentTransformer2 {
private static final Log logger = LogFactory.getLog(ImageTransformer.class);
static {
logger.info("Created ImageTransformer");
}
protected void transformInternal(ContentReader contentReader, ContentWriter contentWriter, TransformationOptions transformationOptions) throws Exception {
logger.info("transformInternal" );
// put some water on the image
}
public boolean isTransformable(String sourceMimetype, String targetMimetype, TransformationOptions transformationOptions) {
logger.info("getReliability - sourceMimetype :" + sourceMimetype + " targetMimetype: " + targetMimetype );
if (sourceMimetype.equals(MimetypeMap.MIMETYPE_IMAGE_JPEG)
|| sourceMimetype.equals(MimetypeMap.MIMETYPE_IMAGE_PNG)
|| sourceMimetype.equals(MimetypeMap.MIMETYPE_IMAGE_GIF) &&
targetMimetype.equals(MimetypeMap.MIMETYPE_IMAGE_JPEG)) {
return true;
} else {
return false;
}
}
}
According to http://docs.alfresco.com/3.4/index.jsp?topic=%2Fcom.alfresco.Enterprise_3_4_0.doc%2Ftasks%2Fcontenttrans-customize.html the file
content-services-context.xml is added to c:\Alfresco\tomcat\shared\classes\alfresco\extension\
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
...
<!-- Content Transformations -->
<bean id="transformer.XYZImages" class="com.xyz.ImageTransformer" parent="baseContentTransformer" >
<property name="explicitTransformations">
<list>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>image/jpeg</value></property>
<property name="targetMimetype"><value>image/jpeg</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>image/png</value></property>
<property name="targetMimetype"><value>image/jpeg</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>image/gif</value></property>
<property name="targetMimetype"><value>image/jpeg</value></property>
</bean>
</list>
</property>
</bean>
</beans>
When Alfresco server is restarted, there is no log logger.info("Created ImageTransformer");
Is it possible to achieve this process? How to call the image transformer from the content rule?
have you tried using webscript instead of Java:
https://code.google.com/p/alfresco-pdf-toolkit/
Related
Im having a problem with a spring-mvc project. The #autowiring is not creating the beans required. Ive worked on this for over 4 days and followed all the search results. But nothing has worked. Can someone please take a look. Thank You
The error stack is this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productsController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.davis.ty.service.ProductsService com.davis.ty.controller.ProductsController.productsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.davis.ty.service.ProductsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
My servlet.xml is:
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:annotation-config />
<context:component-scan base-package="com.davis.ty" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
My controller is:
package com.davis.ty.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.davis.ty.domain.Products;
import com.davis.ty.service.ProductsService;
#Controller
public class ProductsController {
#Autowired
private ProductsService productsService;
#RequestMapping(value = "/index", method = RequestMethod.GET)
public String listProducts (Map<String, Object> map) {
System.out.println("index");
map.put("products", new Products());
map.put("productsList", productsService.listProducts());
return "index";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addProducts(#ModelAttribute("products")
Products products, BindingResult result) {
productsService.addProducts(products);
return "redirect:/index";
}
#RequestMapping("/delete/{Id}")
public String deleteProducts(#PathVariable("Id")
Integer Id) {
productsService.removeProducts(Id);
return "redirect:/index";
}
}
My service program is:
package com.davis.ty.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.davis.ty.dao.ProductsDAO;
import com.davis.ty.domain.Products;
#Service
public class ProductsServiceImpl {
#Autowired
private ProductsDAO productsDAO;
#Transactional
public void addProducts(Products products){
productsDAO.addProduct(products);
}
#Transactional
public List<Products> listProducts() {
return productsDAO.listProducts();
}
#Transactional
public void removeProducts(Integer id) {
productsDAO.removeProducts(id);
}
}
Well, your ProductsServiceImpl class doesn't implement ProductsService... so there's no way that bean is injected in a field of type ProductsService.
From my experience, I just add #Repository at my DAO, maybe you can try to use it too
#Repository
public class ProductsDAO
{
}
How Spring autowire works is, Spring application context scans for all the classes inside the package and sub packages, specified by the component scan and internally creates a map by Type and Name. Incase of Type, value can be List of implementing classes, and by name its one.
Then whenever a #Autowire if encounter,
first it check by Type, so if you autowire using interface, it checks for all the implementation of that interface, and if only 1 if found then inject the same. (In case more then 1 is found, then you need to qaulify using the Qualifier and give proper name.
If above fails, if check by name, and injects.
If both fails, if gives NoSuchBeanDefinitionException,
So in your case, you have set the component scan, which is correct. Then while autowiring, you are giving Interface class name and the implementation class does not implements interface. So type check is failing, and also the by name is also failing, and hence you are getting NoSuchBeanDefinitionException.
To fix this, you will need to do what #JB Nizet is suggesting, so that #1 works and bean gets injected properly.
Add implements ProductService after public class ProductsServiceImpl
create a service interface and implement the interface method in service Impl class with #Overrride annotation.
public interface ProductService{
List<Product> getProducts();
}
And then
#Service
public class ProductsServiceImpl implements ProductService{
#Override
public List<Product> getProducts() {
return productRepository.findAll();
}
I want to use data caching with ehcache in my portlet. I use Spring MVC and liferay portal. If I want to use Cacheable annotation, empty data file is generated.
SocialGraphUI-portlet.xml
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<context:component-scan base-package="socialgraphui" />
<cache:annotation-driven />
<cache:annotation-driven cache-manager="cacheManager" mode="proxy" proxy-target-class="true" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="/WEB-INF/ehcache.xml" p:shared="true" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.GsonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- Spring MVC Message Source -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="useCodeAsDefaultMessage" value="true"/>
<property name="basenames">
<list>
<value>content.socialGraph</value>
</list>
</property>
</bean>
</beans>
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="user.dir"/>
<defaultCache eternal="true" overflowToDisk="true" diskPersistent="true" />
<cache name="socialGraphCache" eternal="true" overflowToDisk="true" diskPersistent="true" />
</ehcache>
SocialGraphViewController.java
package socialgraphui.controller;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.liferay.portal.kernel.util.ParamUtil;
import socialgraphui.model.Edge;
import socialgraphui.model.Message;
import socialgraphui.model.Node;
import socialgraphui.model.SocialGraph;
import socialgraphui.service.SocialGraphService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.log4j.Logger;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.portlet.bind.annotation.ActionMapping;
import org.springframework.web.portlet.bind.annotation.RenderMapping;
import org.springframework.web.portlet.bind.annotation.ResourceMapping;
/**
*
* Controller for VIEW mode of portlet
*/
#Controller("socialGraphViewController")
#RequestMapping(value = "VIEW")
public class SocialGraphViewController{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final Logger logger = Logger.getLogger(SocialGraphViewController.class);
// -- auto-wiring of service dependency
#Autowired
#Qualifier("SGService")
private SocialGraphService socialGraphService;
public void setSocialGraphService(SocialGraphService service){
this.socialGraphService = service;
}
#ModelAttribute(value="socialgraph")
public SocialGraph getSocialGraph(){
return socialGraphService.getSocialGraph();
}
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(PersonDefinitionTypeList.class, new PersonDefinitionTypeListEditor());
}
#ActionMapping(SocialGraphPortletConstants.SUBMIT_FILTER)
public void handleActionRequest(ActionRequest request, ActionResponse response, PortletSession session)throws Exception {
logger.info("handleActionRequest in was executed");
...
}
#RenderMapping
public String handleRenderRequest(RenderRequest request, RenderResponse response, ModelMap model, Locale locale, PortletSession session) {
logger.info("handleRenderRequest was executed");
...
return SocialGraphPortletConstants.VIEW;
}
}
I want to cache result of service constructor, but not sure if I do it in proper way.
SocialGraphServiceImpl.java
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import socialgraphui.controller.SocialGraphViewController;
import socialgraphui.model.Discussion;
import socialgraphui.model.Edge;
import socialgraphui.model.Email;
import socialgraphui.model.Message;
import socialgraphui.model.Node;
import socialgraphui.model.PhoneCall;
import socialgraphui.model.SocialGraph;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
*
*/
#Service(value="SGService")
public class SocialGraphServiceImpl implements SocialGraphService{
private SocialGraph socialgraph = new SocialGraph();
private CreateObjects crObjects = new CreateObjects();
public SocialGraphServiceImpl(){
this.fillGraph();
}
#Override
#Cacheable(value = "socialGraphCache")
public SocialGraph fillGraph(){
this.socialgraph = crObjects.createObjects();
return this.socialgraph;
}
}
And here is what I want to cache.
SocialGraph.java
package socialgraphui.model;
import java.io.Serializable;
import java.util.List;
public class SocialGraph implements Serializable{
private static final long serialVersionUID = -6977846672304367384L;
private List<Node> nodes;
private List<Edge> edges;
public List<Node> getNodes() {
return nodes;
}
public void setNodes(List<Node> nodes) {
this.nodes = nodes;
}
public List<Edge> getEdges() {
return edges;
}
public void setEdges(List<Edge> edges) {
this.edges = edges;
}
}
When I deploy the portlet, I don't get any errors, but generated cache file is empty.
I have same problem and it cause due to i didn't implement all object(class) that used in main object that i want to save in disk.
for more detail see this example.
public class User implements Serializable{
private Address address; // this object(class) not implements Serializable
}
so after implements for all class it works correctly.
I'm new to Spring MVC and I'm trying to understand the following code
package com.companyname.springapp.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.companyname.springapp.service.PriceIncrease;
import com.companyname.springapp.service.ProductManager;
#Controller
#RequestMapping(value="/priceincrease.htm")
public class PriceIncreaseFormController {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
#Autowired
private ProductManager productManager;
#RequestMapping(method = RequestMethod.POST)
public String onSubmit(#Valid PriceIncrease priceIncrease, BindingResult result)
{
if (result.hasErrors()) {
return "priceincrease";
}
int increase = priceIncrease.getPercentage();
logger.info("Increasing prices by " + increase + "%.");
productManager.increasePrice(increase);
return "redirect:/hello.htm";
}
#RequestMapping(method = RequestMethod.GET)
protected PriceIncrease formBackingObject(HttpServletRequest request) throws ServletException {
PriceIncrease priceIncrease = new PriceIncrease();
priceIncrease.setPercentage(15);
return priceIncrease;
}
public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}
public ProductManager getProductManager() {
return productManager;
}
}
As far as I know the BindingResult is an interface and the onSubmit method receives a BindingResult object. What I don't understand is: Who implemented this interface to create the object and where is that implementation?
Here is the 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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="productManager" class="com.companyname.springapp.service.SimpleProductManager">
<property name="products">
<list>
<ref bean="product1"/>
<ref bean="product2"/>
<ref bean="product3"/>
</list>
</property>
</bean>
<bean id="product1" class="com.companyname.springapp.domain.Product">
<property name="description" value="Lamp"/>
<property name="price" value="5.75"/>
</bean>
<bean id="product2" class="com.companyname.springapp.domain.Product">
<property name="description" value="Table"/>
<property name="price" value="75.25"/>
</bean>
<bean id="product3" class="com.companyname.springapp.domain.Product">
<property name="description" value="Chair"/>
<property name="price" value="22.79"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
<!-- Scans the classpath of this application for #Components to deploy as beans -->
<context:component-scan base-package="com.companyname.springapp.web" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
I don't if this helps but I'm using Tomcat 7.0 and whole code is in here: http://docs.spring.io/docs/Spring-MVC-step-by-step/
Who implemented this interface to create the object and where is that implementation?
Implemented in the Spring framework and instantiated by your context.
In the above example BeanPropertyBindingResult.class is exact implementation of BindingResult instantiated
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/validation/BeanPropertyBindingResult.html
I am trying to use bootstrap to style my app but I won't apply the styles. This is what is in my JSP
<c:url value="css/bootstrap.min.css" var="cssBoostrap" />
<link href="${cssBootstrap}" rel="stylesheet">
This css folder is on the same level as WEB-INF not inside of it but it won't work if it is inside of it or even if the files are inside of the view dir. What could the problem possibly be? I no longer get the no mapping error when adding the mapping to my servlet.xml but yet it still doesn't see the file or I can assume it doesn't because no styling is applied, then I change it to link to the online hosted version and all my styles are applied correctly.
Servlet XML
<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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- Scans for annotated #Controllers in the classpath -->
<context:component-scan base-package="com.eaglecrk.recognition" />
<mvc:annotation-driven />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:properties/system.properties</value>
</list>
</property>
</bean>
<!-- messageSource -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:${external.property.directory}PMS.EOTM.SendEmail</value>
</list>
</property>
</bean>
<!-- dataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
</props>
</property>
<property name="packagesToScan" value="com.eaglecrk.recognition.persistence" />
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value = "${email.host}" />
<property name="port" value="${email.port}" />
<property name="username" value="${email.username}" />
<property name="password" value="${email.password}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.ssl.trust">${email.mail.smtp.ssl.trust}</prop>
<prop key="mail.smtp.starttls.enable">${email.mail.smtp.starttls.enable}</prop>
<prop key="mail.smtp.auth">${email.mail.smtp.auth}</prop>
</props>
</property>
</bean>
</beans>
Controller
package com.eaglecrk.recognition.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.eaglecrk.recognition.dao.award.AwardDao;
import com.eaglecrk.recognition.dao.award.AwardDaoInterface;
import com.eaglecrk.recognition.dao.employee.EmployeeDaoInterface;
import com.eaglecrk.recognition.model.AwardTypeModel;
import com.eaglecrk.recognition.model.EmployeeModel;
import com.eaglecrk.recognition.persistence.AwardNomination;
import com.eaglecrk.recognition.persistence.AwardType;
import com.eaglecrk.recognition.persistence.Employee;
import com.eaglecrk.recognition.util.Functions;
import com.eaglecrk.recognition.util.SpringMailSender;
#Controller
public class TestController extends BaseController implements MessageSourceAware {
private static final Logger LOG = LogManager
.getLogger(TestController.class);
#Autowired
private EmployeeDaoInterface employeeDao;
#Autowired
private AwardDaoInterface awardDao;
#Autowired
private SpringMailSender springMailSender;
/**
* #param request
* #return (ModelAndView) object
*/
#RequestMapping(value = "/test", method = RequestMethod.GET)
public ModelAndView test() {
try {
LOG.info("Entered the controller");
springMailSender.sendMail();
} catch (Exception e) {
e.printStackTrace();
}
ModelAndView mav = new ModelAndView();
ArrayList<String> names = new ArrayList<String>();
List<Employee> employees = employeeDao.findAll();
Collections.sort(employees, Functions.lastNameOrder);
for (Employee employee : employees) {
EmployeeModel model = new EmployeeModel(employee);
names.add(model.getLocation().getLocationId() + " " +
model.getFirstName() + " " + model.getLastName());
}
mav.addObject("names", names);
mav.setViewName("test");
return mav;
}
#RequestMapping(value = "/test", method = RequestMethod.POST)
public void addNomination(
#ModelAttribute("SpringWeb") AwardNomination nomination,
ModelMap model) {
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login() {
ModelAndView mav = new ModelAndView();
mav.setViewName("login");
return mav;
}
#RequestMapping(value="/newAwardType", method=RequestMethod.GET)
public ModelAndView addAward() {
ModelAndView mav = new ModelAndView();
ArrayList<AwardTypeModel> models = new ArrayList<AwardTypeModel>();
try{
AwardTypeModel newAwardTypeModel = new AwardTypeModel();
newAwardTypeModel.setActive(false);
newAwardTypeModel.setName("AwardTypeModel.name");
newAwardTypeModel.setDescription("AwardTypeModel.description");
// newAwardTypeModel.setId(123456);
newAwardTypeModel.setCreated(new Date());
newAwardTypeModel.setModified(new Date());
models.add(newAwardTypeModel);
} catch (Exception e){
e.printStackTrace();
}
mav.addObject("awardTypes", models);
mav.addObject("model", new AwardTypeModel());
mav.setViewName("addAward");
return mav;
}
#RequestMapping(value="/addAward", method=RequestMethod.POST)
public String addAwardForm(#ModelAttribute("model") AwardTypeModel model, BindingResult result){
model.setCreated(new Date());
model.setModified(new Date());
AwardType dbo = (AwardType) model.convertToDb();
awardDao.save(dbo);
return "redirect:/test";
}
#Override
public void setMessageSource(MessageSource messageSource) {
// TODO Auto-generated method stub
}
}
Create one folder by name resources at same level as WEB-INF as shown below:
WebApp-|
| - resources -|
| |-styles-|
| | |-bootstrap.min.css
| |
| |-javascript-|
| |-example.js
|
| - WEB-INF
Include the following line in your servlet xml:
<mvc:resources mapping="/resources/**" location="/resources/"/>
Access these resources in your jsp as:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<link href="<c:url value="/resources/styles/bootstrap.min.css" />" rel="stylesheet">
<script src="<c:url value="/resources/javascript/example.js" />"></script>
....
You should declare in your dispatcher servlet config the location of you resources (e.g js, css, img etc.) :
<mvc:resources mapping="/public/**" location="/public/" />
location contains the path to your resources folder. mapping is how you call your resources in your jsp.
Don't forget to declare your mvc namespace in dispatcher config.
Following Prasads Answer above if you need Java based configuration for the same use -
#Configuration
#ComponentScan("com.eaglecrk.recognition")
#EnableWebMvc
public class SpringConfig extends WebMvcConfigurerAdapter {
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Also if you are using xml based configuration don't forget <mvc:default-servlet-handler/>
For a recent project we wanted to support XML and another format for our resopnses.
However, we could not control the Accept header. Hence we configured a ContentNegotiatingViewResolver to use a request parameter instead:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorParameter" value="true" />
<property name="parameterName" value="format" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="foo" value="application/x-foo" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-xml" />
</bean>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-foo" />
</bean>
</list>
</property>
</bean>
Now however, I was wondering if I could move to using #ResponseBody and HttpMessageConverter implementations to simplify the amount of code I need to maintain.
However, is there a similar way to ensure that a reqeust parameter is used for content negotiation, instead of the Accept header?
There is a workaround, as described at https://jira.springframework.org/browse/SPR-7517
Create a subclass of AnnotationMethodHandlerAdapter:
package org.nkl.spring;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
public class MyAnnotationMethodHandlerAdapter extends AnnotationMethodHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(MyAnnotationMethodHandlerAdapter.class);
private String requestParam = "accept";
private Map<String, MediaType> mediaTypesMap;
#Override protected HttpInputMessage createHttpInputMessage(HttpServletRequest request) throws Exception {
HttpInputMessage message = super.createHttpInputMessage(request);
String accept = request.getParameter(requestParam);
if (accept == null || accept.isEmpty()) {
logger.info(String.format("Request parameter [%s] not found. Using standard HttpInputMessage", requestParam));
return message;
} else {
logger.info(String.format("Request parameter [%s] was [%s]", requestParam, accept));
MediaType mediaType = mediaTypesMap.get(accept);
if (mediaType == null) {
logger.info(String.format("Suitable MediaType not found. Using standard HttpInputMessage"));
return message;
} else {
logger.info(String.format("Suitable MediaType [%s] found. Using custom HttpInputMessage", mediaType));
return new MyHttpInputMessage(message, mediaTypesMap.get(accept));
}
}
}
public void setMediaTypesMap(Map<String, MediaType> mediaTypesMap) {
this.mediaTypesMap = mediaTypesMap;
}
public void setRequestParam(String requestParam) {
this.requestParam = requestParam;
}
}
Create a Decorator of HttpInputMessage:
package org.nkl.spring;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
public class MyHttpInputMessage implements HttpInputMessage {
private HttpInputMessage delegate;
public MyHttpInputMessage(HttpInputMessage delagate, MediaType mediaType) {
this.delegate = delagate;
this.delegate.getHeaders().setAccept(Arrays.asList(mediaType));
}
#Override public InputStream getBody() throws IOException {
return this.delegate.getBody();
}
#Override public HttpHeaders getHeaders() {
return this.delegate.getHeaders();
}
}
Configure your bean like:
<bean class="org.nkl.spring.MyAnnotationMethodHandlerAdapter">
<property name="requestParam" value="format" />
<property name="mediaTypesMap">
<util:map>
<entry key="plain" value="text/plain" />
<entry key="xml" value="text/xml" />
</util:map>
</property>
<property name="messageConverters">
<util:list>
... converters go here ...
</util:list>
</property>
</bean>
Newer versions of Spring can now do this. The ContentNegotiationManagerFactoryBean can create a content negotiation manager that does precisely what you want here. See my answer to a related question.