Rectangle 27 122

EDIT as a "comments follow up" => to be Turing Complete:

AnnotationConfigWebApplicationContext
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            org.package.YouConfigurationAnnotatedClass
        </param-value>
    </init-param>
</servlet>
@EnableWebMvc
web.xml
<web-app>
  <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
       instead of the default XmlWebApplicationContext -->
  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
  </context-param>

  <!-- Configuration locations must consist of one or more comma- or space-delimited
       fully-qualified @Configuration classes. Fully-qualified packages may also be
       specified for component-scanning -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.AppConfig</param-value>
  </context-param>

  <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Declare a Spring MVC DispatcherServlet as usual -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
           instead of the default XmlWebApplicationContext -->
      <init-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </init-param>
      <!-- Again, config locations must consist of one or more comma- or space-delimited
           and fully-qualified @Configuration classes -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.acme.web.MvcConfig</param-value>
      </init-param>
  </servlet>

  <!-- map all requests for /app/* to the dispatcher servlet -->
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
</web-app>

Hi, I am not using Spring MVC here, only JSF and Spring 3.1 RC1. Though I wrote this servlet in my web.xml but still got same error "no ContextLoaderListener registered". I then did entry for listener class of spring and then got other error of applicationContext.xml not found. I hope I am making my point clear.

I never received you edit request, but I updated my answer with an example of a full web.xml form the Spring official documentation.

In my web application config i had to have <load-on-startup>1</load-on-startup> in dispatcher servlet. Without this dispatcher have not be loaded

java - How to register Spring @Configuration annotated class instead o...

java spring spring-3 spring-annotations
Rectangle 27 122

EDIT as a "comments follow up" => to be Turing Complete:

AnnotationConfigWebApplicationContext
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            org.package.YouConfigurationAnnotatedClass
        </param-value>
    </init-param>
</servlet>
@EnableWebMvc
web.xml
<web-app>
  <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
       instead of the default XmlWebApplicationContext -->
  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
  </context-param>

  <!-- Configuration locations must consist of one or more comma- or space-delimited
       fully-qualified @Configuration classes. Fully-qualified packages may also be
       specified for component-scanning -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.AppConfig</param-value>
  </context-param>

  <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Declare a Spring MVC DispatcherServlet as usual -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
           instead of the default XmlWebApplicationContext -->
      <init-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </init-param>
      <!-- Again, config locations must consist of one or more comma- or space-delimited
           and fully-qualified @Configuration classes -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.acme.web.MvcConfig</param-value>
      </init-param>
  </servlet>

  <!-- map all requests for /app/* to the dispatcher servlet -->
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
</web-app>

Hi, I am not using Spring MVC here, only JSF and Spring 3.1 RC1. Though I wrote this servlet in my web.xml but still got same error "no ContextLoaderListener registered". I then did entry for listener class of spring and then got other error of applicationContext.xml not found. I hope I am making my point clear.

I never received you edit request, but I updated my answer with an example of a full web.xml form the Spring official documentation.

In my web application config i had to have <load-on-startup>1</load-on-startup> in dispatcher servlet. Without this dispatcher have not be loaded

java - How to register Spring @Configuration annotated class instead o...

java spring spring-3 spring-annotations
Rectangle 27 3

In the web.xml file you are specifying that Java configuration will be used to setup the MVC components, however the MVC components are attempted to be setup within the applicationContext.xml file.

The ContextLoaderListener in web.xml is setup to launch the /WEB-INF/applicationContext.xml configuration file. The container setup by applicationContext.xml should not include the MVC components but should be used for registering beans outside of the MVC scope such as those for data persistence.

If you truly want to use Java Configuration to setup the Spring MVC components you must move all of the Spring MVC components established in the applicationContext.xml file to a Java class annotated with @Configuration and translate the XML beans to their appropriate configurations in Java.

Thanks @KenvinBowersox. The real problem was the fact that I was mixing xml configuration with java configuration. I had some classes annotated with "@Configuration". Removing these classes resolved my problems.

java - Error when adding in applicationContext...

java xml spring hibernate spring-mvc
Rectangle 27 66

The Java XML parser that spring uses will read the schemaLocation values and try to load them from the internet, in order to validate the XML file. Spring, in turn, intercepts those load requests and serves up versions from inside its own JAR files.

If you omit the schemaLocation, then the XML parser won't know where to get the schema in order to validate the config.

Wouldn't the XML parser search the class path?

@skaffman, Does it mean that when I run maven build of spring-based projhect with -o (offline) flag the build will fail despite the fact that all the dependencies are available in my local repository?

@HDave But what would XML parser be looking for, schema could have any name

Technically, the XML parser will firstly try to load the schema from internet, if not found or internet access is not available, it will search *.xsd file locally from class path, if still not found, it will be omitted.

xsd - what is the use of xsi:schemaLocation? - Stack Overflow

xsd
Rectangle 27 66

The Java XML parser that spring uses will read the schemaLocation values and try to load them from the internet, in order to validate the XML file. Spring, in turn, intercepts those load requests and serves up versions from inside its own JAR files.

If you omit the schemaLocation, then the XML parser won't know where to get the schema in order to validate the config.

Wouldn't the XML parser search the class path?

@skaffman, Does it mean that when I run maven build of spring-based projhect with -o (offline) flag the build will fail despite the fact that all the dependencies are available in my local repository?

@HDave But what would XML parser be looking for, schema could have any name

Technically, the XML parser will firstly try to load the schema from internet, if not found or internet access is not available, it will search *.xsd file locally from class path, if still not found, it will be omitted.

xsd - what is the use of xsi:schemaLocation? - Stack Overflow

xsd
Rectangle 27 66

The Java XML parser that spring uses will read the schemaLocation values and try to load them from the internet, in order to validate the XML file. Spring, in turn, intercepts those load requests and serves up versions from inside its own JAR files.

If you omit the schemaLocation, then the XML parser won't know where to get the schema in order to validate the config.

Wouldn't the XML parser search the class path?

@skaffman, Does it mean that when I run maven build of spring-based projhect with -o (offline) flag the build will fail despite the fact that all the dependencies are available in my local repository?

@HDave But what would XML parser be looking for, schema could have any name

Technically, the XML parser will firstly try to load the schema from internet, if not found or internet access is not available, it will search *.xsd file locally from class path, if still not found, it will be omitted.

xsd - what is the use of xsi:schemaLocation? - Stack Overflow

xsd
Rectangle 27 66

The Java XML parser that spring uses will read the schemaLocation values and try to load them from the internet, in order to validate the XML file. Spring, in turn, intercepts those load requests and serves up versions from inside its own JAR files.

If you omit the schemaLocation, then the XML parser won't know where to get the schema in order to validate the config.

Wouldn't the XML parser search the class path?

@skaffman, Does it mean that when I run maven build of spring-based projhect with -o (offline) flag the build will fail despite the fact that all the dependencies are available in my local repository?

@HDave But what would XML parser be looking for, schema could have any name

Technically, the XML parser will firstly try to load the schema from internet, if not found or internet access is not available, it will search *.xsd file locally from class path, if still not found, it will be omitted.

xsd - what is the use of xsi:schemaLocation? - Stack Overflow

xsd
Rectangle 27 9

Bumping up an old question here, but with recent versions of Spring (v3.0+) now you can get rid of web.xml altogether, provided you are deploying your app on a web container that supports Servlet 3.0+.

One can implement Spring's WebApplicationInitializer interface to do the same configurations that one would do in web.xml. This implementation class will be automatically detected by Spring 3.0+ app running on Servlet 3.0+ containers. If the set up is rather simple, you could instead use another class provided by Spring as shown below. All one does here is to set the @Configuration classes and list out the servlet mappings. Keeps the setup extremely simple.

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] {AppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
                 "*.html"
                ,"*.json"
                ,"*.do"};
    }
}

If you do try to get rid of web.xml be sure you're using a container that supports Servlet 3.0 like Tomcat 7.0.57. P.S. Steve, nice work with the leading commas!

That's true. I'll throw that in the answer. Thanks

java - How to register Spring @Configuration annotated class instead o...

java spring spring-3 spring-annotations
Rectangle 27 9

Bumping up an old question here, but with recent versions of Spring (v3.0+) now you can get rid of web.xml altogether, provided you are deploying your app on a web container that supports Servlet 3.0+.

One can implement Spring's WebApplicationInitializer interface to do the same configurations that one would do in web.xml. This implementation class will be automatically detected by Spring 3.0+ app running on Servlet 3.0+ containers. If the set up is rather simple, you could instead use another class provided by Spring as shown below. All one does here is to set the @Configuration classes and list out the servlet mappings. Keeps the setup extremely simple.

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] {AppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
                 "*.html"
                ,"*.json"
                ,"*.do"};
    }
}

If you do try to get rid of web.xml be sure you're using a container that supports Servlet 3.0 like Tomcat 7.0.57. P.S. Steve, nice work with the leading commas!

That's true. I'll throw that in the answer. Thanks

java - How to register Spring @Configuration annotated class instead o...

java spring spring-3 spring-annotations
Rectangle 27 1

If what you want is to specify the imported XML file name outside applicationContext.xml so that you could replace applicationContext.xml without losing the configuration of the imported XML file path, you can just add an intermediate Spring beans XML file, say, confSelector.xml, so that applicationContext.xml imports confSelector.xml and confSelector.xml only contains an <import> element that refers to the suitable custom beans XML file.

Another means that might be of use are XML entities (defined by adding <!ENTITY ... > elements into the DTD declaration at the beginning of XML). These allow importing XML fragments from other files and provide "property placeholder"-like functionality for any XML file.

Neither of these solutions allows you to have the configuration file in Java's .properties format, though.

java - Import Spring config file based on property in .properties file...

java spring configuration
Rectangle 27 15

Problem is due to problem in my applicationContext.xml vs spring-servlet.xml - it was scoping issue between the beans.

java - Spring @Value is not resolving to value from property file - St...

java spring spring-properties
Rectangle 27 1

In your example you use the Spring ImportResource annotation which is used to import bean definitions. That is why Spring tries to validate the DMN XML file you specified and correctly fails as it isn't in the correct format. Remove this line.

http://www.omg.org/spec/DMN/20151101/dmn11.xsd
InputStream inputStream = DishDecider.class.getResourceAsStream("/dish-decision.dmn11.xml");

one doubt, I am not good in xml but just curious if I brows xsd url for dmn in browser it does not work. Then how it gets xsd to validate xml?

The XSD is only validated by the Camunda DMN Model API which has the XSD as a resource. The one I linked in a previous comment.

java - SAXParseException : Cannot find the declaration of element 'def...

java spring-boot camunda
Rectangle 27 4

Since this is a popular question, I would also like to point out that java can validate against a "referred to" xsd, for instance if the .xml file itself specifies an XSD, using xsi:SchemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) as stated here:

or SchemaLocation (always a list of namespace to xsd mappings)

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd">
  ...

"If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();

and this works for multiple namespaces, etc. The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll go out and hit the network with each and every validation, not always optimal.

Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):

public static void verifyValidatesInternalXsd(String filename) throws Exception {
    InputStream xmlStream = new new FileInputStream(filename);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
    DocumentBuilder builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new RaiseOnErrorHandler());
    builder.parse(new InputSource(xmlStream));
    xmlStream.close();
  }

  public static class RaiseOnErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void error(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void fatalError(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
  }

You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:

Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
                                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
  @Override
  public LSInput resolveResource(String type, String namespaceURI,
                                 String publicId, String systemId, String baseURI) {
    InputSource is = new InputSource(
                           getClass().getResourceAsStream(
                          "some_local_file_in_the_jar.xsd"));
                          // or lookup by URI, etc...
    return new Input(is); // for class Input see 
                          // https://stackoverflow.com/a/2342859/32453
  }
});
validator.validate(xmlFile);

java - What's the best way to validate an XML file against an XSD file...

java xml validation xsd
Rectangle 27 4

Since this is a popular question, I would also like to point out that java can validate against a "referred to" xsd, for instance if the .xml file itself specifies an XSD, using xsi:SchemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) as stated here:

or SchemaLocation (always a list of namespace to xsd mappings)

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd">
  ...

"If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();

and this works for multiple namespaces, etc. The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll go out and hit the network with each and every validation, not always optimal.

Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):

public static void verifyValidatesInternalXsd(String filename) throws Exception {
    InputStream xmlStream = new new FileInputStream(filename);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
    DocumentBuilder builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new RaiseOnErrorHandler());
    builder.parse(new InputSource(xmlStream));
    xmlStream.close();
  }

  public static class RaiseOnErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void error(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void fatalError(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
  }

You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:

Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
                                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
  @Override
  public LSInput resolveResource(String type, String namespaceURI,
                                 String publicId, String systemId, String baseURI) {
    InputSource is = new InputSource(
                           getClass().getResourceAsStream(
                          "some_local_file_in_the_jar.xsd"));
                          // or lookup by URI, etc...
    return new Input(is); // for class Input see 
                          // https://stackoverflow.com/a/2342859/32453
  }
});
validator.validate(xmlFile);

java - What's the best way to validate an XML file against an XSD file...

java xml validation xsd
Rectangle 27 4

Since this is a popular question, I would also like to point out that java can validate against a "referred to" xsd, for instance if the .xml file itself specifies an XSD, using xsi:SchemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) as stated here:

or SchemaLocation (always a list of namespace to xsd mappings)

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.example.com/document http://www.example.com/document.xsd">
  ...

"If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();

and this works for multiple namespaces, etc. The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll go out and hit the network with each and every validation, not always optimal.

Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):

public static void verifyValidatesInternalXsd(String filename) throws Exception {
    InputStream xmlStream = new new FileInputStream(filename);
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                 "http://www.w3.org/2001/XMLSchema");
    DocumentBuilder builder = factory.newDocumentBuilder();
    builder.setErrorHandler(new RaiseOnErrorHandler());
    builder.parse(new InputSource(xmlStream));
    xmlStream.close();
  }

  public static class RaiseOnErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void error(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
    public void fatalError(SAXParseException e) throws SAXException {
      throw new RuntimeException(e);
    }
  }

You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:

Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
                                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
  @Override
  public LSInput resolveResource(String type, String namespaceURI,
                                 String publicId, String systemId, String baseURI) {
    InputSource is = new InputSource(
                           getClass().getResourceAsStream(
                          "some_local_file_in_the_jar.xsd"));
                          // or lookup by URI, etc...
    return new Input(is); // for class Input see 
                          // https://stackoverflow.com/a/2342859/32453
  }
});
validator.validate(xmlFile);

java - What's the best way to validate an XML file against an XSD file...

java xml validation xsd
Rectangle 27 2

IMHO, it is a bad idea to load the whole CSV in memory unless :

  • you are sure it will always be very small (and what if a user click on wrong file ?)
  • the validation is global (only real use case, but does not seem to be here)
  • your application will never be used in a production context under serious load

You should either stick to the MultipartFile object, or use a wrapper exposing the InputStream (and eventually other informations you could need) if you do not want to tie your business classes to Spring.

Then you carefully design, code and test a method taking an InputStream as input, reads it line by line and call line by line methods to validate and insert data. Something like

class CsvLoader {
@Autowired Verifier verifier;
@Autowired Loader loader;

    void verifAndLoad(InputStream csv) {
        // loop through csv
        if (verifier.verify(myObj)) {
            loader.load(myObj);
        }
        else {
            // log the problem eventually store the line for further analysis
        }
        csv.close();
    }
}

That way, your application only uses the memory it really needs, only looping once other the file.

First, I would split validation in 2. Formal validation is in controller layer and only controls that :

  • the file size and mimetype seems Ok (eg : size > 12 && mimetype = text/csv)

The validation of the content is IMHO a business layer validation and can happen later. In this pattern, SiteCSVFileValidator would only test csv for mimetype and size.

Normally, you avoid directly using Spring classes from business classes. If it is not a concern, the controller directly sends the MultipartFile to a service object, passing also the BindingResult to populate directly the eventual error messages. The controller becomes :

@RequestMapping(value="/new", method = RequestMethod.POST)
public String newCustomer(@Valid @ModelAttribute("customerForm") CustomerForm customerForm, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "NewCustomer"; // only external validation
    } else {

        /* 
           validation has passed, so now we must:
           1) open customerForm.csvFile 
           2) loop through it to validate each line and populate customerForm.customer.sites 
        */

        customerService.insert(customerForm.customer, customerForm.csvFile, bindingResult);
        if (bindingResult.hasErrors()) {
            return "NewCustomer"; // only external validation
        } else {
            return "CustomerList";
        }
    }
}

In service class we have

insert(Customer customer, MultipartFile csvFile, Errors errors) {
    // loop through csvFile.getInputStream populating customer.sites and eventually adding Errors to errors
    if (! errors.hasErrors) {
        // actually insert through DAO
    }
}
customerService.insert(customerForm.customer, customerForm.csvFile, bindingResult);
List<Integer> linesInError = new ArrayList<Integer>();
customerService.insert(customerForm.customer, customerForm.csvFile.getInputStream(), linesInError);
if (! linesInError.isEmpty()) {
    // populates bindingResult with convenient error messages
}

Then the service class only adds line numbers where errors where detected to linesInError but it only gets the InputStream, where it could need say the original file name. You can pass the name as another parameter, or use a wrapper class :

class CsvFile {

    private String name;
    private InputStream inputStream;

    CsvFile(MultipartFile file) {
        name = file.getOriginalFilename();
        inputStream = file.getInputStream();
    }
    // public getters ...
}

and call

customerService.insert(customerForm.customer, new CsvFile(customerForm.csvFile), linesInError);

with no direct Spring dependancies

Thanks for your feedback; I have updated my original question to show my MVC config which limits file uploads to 1MB (probably should have included this to start with!). The CSV files are relatively small (5KB on average) and as a result the double-loop shouldn't cause a problem, it just doesn't seem a tidy solution to have to open & read the file twice. Your CsvLoader answer interests me but I'm not sure what you mean by "use a wrapper exposing the InputStream" - can you elaborate please? (More sample code would really help).

java - Converting & validating CSV file upload in Spring MVC - Stack O...

java validation spring-mvc csv
Rectangle 27 4

notmatch.password
message_en_US.properties
notmatch.password = Inccorect password

and change the basename to

<beans:property name="basename"
            value="/WEB-INF/resources/message" />

java - Spring : message.properties file not working - Stack Overflow

java xml spring validation
Rectangle 27 3

@ModelAttribute
BindingResult

. You also should add MultipartFile to form class (Store) if it is part of it.

Store {

    /* Your other fields */

    @NotNull
    private  MultipartFile file;

    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file= file;
    }
}

Thank you so much!!! Where can I find the possible different permutations of method signatures and the types of parameters and their order if enforced for the annotated controller methods? I couldn't find details in the documentation. Thank you again so much!!!

java - spring 3 auto form field validation with file upload - Stack Ov...

java spring
Rectangle 27 17

Is it possible to use Spring @Value, to map values from properties file to the HashMap?

Yes, it is. With a little help of code and Spel.

Firstly, consider this singleton Spring-bean (you should scan it):

@Component("PropertySplitter")
public class PropertySplitter {

    /**
     * Example: one.example.property = KEY1:VALUE1,KEY2:VALUE2
     */
    public Map<String, String> map(String property) {
        return this.map(property, ",");
    }

    /**
     * Example: one.example.property = KEY1:VALUE1.1,VALUE1.2;KEY2:VALUE2.1,VALUE2.2
     */
    public Map<String, List<String>> mapOfList(String property) {
        Map<String, String> map = this.map(property, ";");

        Map<String, List<String>> mapOfList = new HashMap<>();
        for (Entry<String, String> entry : map.entrySet()) {
            mapOfList.put(entry.getKey(), this.list(entry.getValue()));
        }

        return mapOfList;
    }

    /**
     * Example: one.example.property = VALUE1,VALUE2,VALUE3,VALUE4
     */
    public List<String> list(String property) {
        return this.list(property, ",");
    }

    /**
     * Example: one.example.property = VALUE1.1,VALUE1.2;VALUE2.1,VALUE2.2
     */
    public List<List<String>> groupedList(String property) {
        List<String> unGroupedList = this.list(property, ";");

        List<List<String>> groupedList = new ArrayList<>();
        for (String group : unGroupedList) {
            groupedList.add(this.list(group));
        }

        return groupedList;

    }

    private List<String> list(String property, String splitter) {
        return Splitter.on(splitter).omitEmptyStrings().trimResults().splitToList(property);
    }

    private Map<String, String> map(String property, String splitter) {
        return Splitter.on(splitter).omitEmptyStrings().trimResults().withKeyValueSeparator(":").split(property);
    }

}
PropertySplitter
Splitter

Then, in some bean of yours:

@Component
public class MyBean {

    @Value("#{PropertySplitter.map('${service.expiration}')}")
    Map<String, String> propertyAsMap;

}
service.expiration = name1:100,name2:20

It's not exactly what you've asked, because this PropertySplitter works with one single property that is transformed into a Map, but I think you could either switch to this way of specifying properties, or modify the PropertySplitter code so that it matches the more hierarchical way you desire.

How to fill HashMap from java property file with Spring @Value - Stack...

java spring properties-file spring-el
Rectangle 27 17

Is it possible to use Spring @Value, to map values from properties file to the HashMap?

Yes, it is. With a little help of code and Spel.

Firstly, consider this singleton Spring-bean (you should scan it):

@Component("PropertySplitter")
public class PropertySplitter {

    /**
     * Example: one.example.property = KEY1:VALUE1,KEY2:VALUE2
     */
    public Map<String, String> map(String property) {
        return this.map(property, ",");
    }

    /**
     * Example: one.example.property = KEY1:VALUE1.1,VALUE1.2;KEY2:VALUE2.1,VALUE2.2
     */
    public Map<String, List<String>> mapOfList(String property) {
        Map<String, String> map = this.map(property, ";");

        Map<String, List<String>> mapOfList = new HashMap<>();
        for (Entry<String, String> entry : map.entrySet()) {
            mapOfList.put(entry.getKey(), this.list(entry.getValue()));
        }

        return mapOfList;
    }

    /**
     * Example: one.example.property = VALUE1,VALUE2,VALUE3,VALUE4
     */
    public List<String> list(String property) {
        return this.list(property, ",");
    }

    /**
     * Example: one.example.property = VALUE1.1,VALUE1.2;VALUE2.1,VALUE2.2
     */
    public List<List<String>> groupedList(String property) {
        List<String> unGroupedList = this.list(property, ";");

        List<List<String>> groupedList = new ArrayList<>();
        for (String group : unGroupedList) {
            groupedList.add(this.list(group));
        }

        return groupedList;

    }

    private List<String> list(String property, String splitter) {
        return Splitter.on(splitter).omitEmptyStrings().trimResults().splitToList(property);
    }

    private Map<String, String> map(String property, String splitter) {
        return Splitter.on(splitter).omitEmptyStrings().trimResults().withKeyValueSeparator(":").split(property);
    }

}
PropertySplitter
Splitter

Then, in some bean of yours:

@Component
public class MyBean {

    @Value("#{PropertySplitter.map('${service.expiration}')}")
    Map<String, String> propertyAsMap;

}
service.expiration = name1:100,name2:20

It's not exactly what you've asked, because this PropertySplitter works with one single property that is transformed into a Map, but I think you could either switch to this way of specifying properties, or modify the PropertySplitter code so that it matches the more hierarchical way you desire.

How to fill HashMap from java property file with Spring @Value - Stack...

java spring properties-file spring-el