Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Sunday, 18 November 2012

Spring Bean XML To Annotation Configuration

Here is an example of converting an XML based bean configuration to a annotation based configuration.

Assuming an XML files contain the following:
<bean id="localeChangeInterceptor"
    class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <property name="paramName" value="lang" />
</bean>
<bean id="handlerMapping"
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
   <property name="interceptors">
       <ref bean="localeChangeInterceptor" />
   </property>
</bean>
The second beans refers to the first one for initialization.

The corresponding Java with annotation configuration is:
@Configuration
public class MyConfig {

    // ...

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {

        LocaleChangeInterceptor result
            = new LocaleChangeInterceptor();

        result.setParamName("lang");

        return result;

    }

    @Bean
    public DefaultAnnotationHandlerMapping handlerMapping() {

        DefaultAnnotationHandlerMapping result
            = new DefaultAnnotationHandlerMapping();

        Object[] interceptors = {
            localeChangeInterceptor()
        };

        result.setInterceptors(interceptors);

        return result;

    }

}

More Spring related posts here.

Monday, 17 September 2012

Spring Security And Annotation Configuration Example

This post is the mix between the Spring MVC with Annotations Example and the Spring Security Configuration Introduction. The code example is available on Github in the Spring-Security-And-Annotation-Config directory.

We are going to add a mandatory login page before one can access the main page of the Spring MVC with Annotations example.

Configuration

First, we create a MyServlet-security.xml file:
<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.springframework.org/schema/security

    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

  <http auto-config="true">
    <intercept-url pattern="/*" access="ROLE_USER"/>
  </http>

  <authentication-manager alias="authenticationManager">
    <authentication-provider>
      <user-service>
        <user authorities="ROLE_USER" name="guest" password="guest"/>
      </user-service>
    </authentication-provider>
  </authentication-manager>

</beans:beans>
We rely on the automatic configuration of Spring security, and we request that one must login with ROLE_USER privilege to access any to page of the website. We set an authentication manager and create a simple guest user login, with the guest password.

We add the security filters under contextConfigLocation:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
  </context-param>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      com.jverstry.Configuration
    </param-value>
  </context-param>

  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
      org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file></welcome-file>
  </welcome-file-list>

</web-app>
At last we add one @ImportSource line in our WebConfig configuration class:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.jverstry")
@ImportResource("/WEB-INF/MyServlet-security.xml")
public class WebConfig extends WebMvcConfigurerAdapter {

  @Bean
  public ViewResolver getViewResolver() {

    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("WEB-INF/pages/");
    resolver.setSuffix(".jsp");

    return resolver;

  }

}

Running The Example

After compiling the project, one can run it using the maven tomcat:run goal. Then, browse:

  http://localhost:9191/spring-mvc-with-annotations/

Login with guest guest:


 ...and access the main page:


More Spring related posts here.

Saturday, 15 September 2012

Explain: xmlns, xsd, xsi:schemaLocation

This post is a reminder/introduction to some XML related terminology and acronyms.

xmlns

xmlns stands for XML namespace. This item is used to declare namespaces in XML documents. It allows one use the XML element and attributes of this namespace in the XML document.

Several namespaces can be declared in a single XML document. In order to avoid name collisions, one can add a prefix (i.e., xmlns:myprefix) to differentiate between same XML elements and attributes.
For example:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
  xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  ... >
    ...
</beans:beans>
The above declares two namespaces, a default one without prefix (security) and one with the beans prefix (beans). One can use all items of the security namespace without prefix, but the elements and the attributes of the bean namespace must be used with the beans prefix, such as <beans:beans ...> and </beans:beans>.

xsd

An xsd file defines a XML schema, that is, how elements and attributes of an XML document can interact with each other. Typically, these xsd files are used to validate XML documents.

xsi:schemaLocation

Once one includes the XML schema instance namespace in a document (typically with xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"), one can specify the XML schema's location against which the XML document should be validated, with xsi:schemaLocation:
xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security
  http://www.springframework.org/schema/security/spring-security-3.1.xsd"

How To Mix Spring XML And Java Configuration?

The @Configuration Spring annotation allows one to perform Spring configuration from Java (such as bean declaration for example). It is possible to implement a Spring application without any XML configuration (see here). It is even possible to get rid of the web application web.xml file too.

However, some Spring modules, such as the security module, still require plain XML configuration. Some applications may refer to old legacy code which has not been converted to Java configuration too.

In this case, one needs to mix Spring XML and Java configuration. This can be achieved with the @ImportResource Spring annotation:
@Configuration
@ImportResource({"classpath:/WEB-INF/spring-security.xml",
"classpath:/WEB-INF/legacy-config.xml"})
public class Config {

    @Bean
    MyBean MyBean() {
        return new MyBean();
    }

}
The above imports two XML files and declares a bean using Java.

More Spring related posts here.

Monday, 13 August 2012

What is web.xml (Deployment Descriptor) in Java?

In Java, all web applications have a web.xml file, also called deployment descriptor, in the \META-INF directory. The main purpose of this file is to provide information about the web application to deploy in the container.

It can be used to declare and configure servlets belonging to the application via descriptor elements. For example, tt helps setting filters, icons or define default welcome pages too.

Here is a web.xml example:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
 version="2.4">

  <display-name>My Application</display-name> 
  <description>My application description</description>

  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>somepackage.MyServletClass</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServletMapping</url-pattern>
  </servlet-mapping>

</web-app>
It defines a web application with one servlet called MyServlet. User requests to:

  http://www.mywebserver.com/MyAppPath/MyServletMapping/...

are sent to MyServlet. The MyAppPath application path is typically defined in the context.xml file. Both files serve different purpose and should not be confused with each other.

What is the context.xml file in a Web Application?

When one creates a default maven web application (from the corresponding archetype), a file called context.xml is automatically be created in /src/main/webapp/META-INF/ if the selected server is Apache Tomcat.

For example:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyApplication"/>
From the Tomcat documentation, this file represents the application withing Tomcat. It contains a very important information: the application path. In other words:

  http://www.mytomcatserver.com/MyApplication/index.html

When multiple applications are deployed on Tomcat, users' requests are sent to the proper application by checking each application's path. Longer matching paths have priority on shorter paths.

This file can be used to set some application configuration too (see the bottom of the Tomcat documentation page mentioned above) or a JNDI resource such as a data source for example.

Sunday, 5 August 2012

JAXB XML Marshalling / Unmarshalling

We are going to perform a simple round trip to convert an JAXB annotated Java object into an XML (marshalling) and back into an XML object (unmarshalling). The code example is available on GitHub in the JAXB-JSON-XML Marshalling directory.

The following is a simple Java object with JAXB annotation:
@XmlRootElement
public class Book {

    private String title;
    private int year;

    public String getTitle() {
        return title;
    }

    @XmlElement
    public void setTitle(String title) {
        this.title = title;
    }

    public int getYear() {
        return year;
    }

    @XmlElement
    public void setYear(int year) {
        this.year = year;
    }

}
The following code performs the round trip:
    public static void main(String[] args) throws JAXBException {

        Book book = new Book();
        book.setTitle("Book title");
        book.setYear(2010);

        // Creating a Marshaller
        JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter result = new StringWriter();
        jaxbMarshaller.marshal(book, result);

        // Printing XML
        String xml = result.toString();
        System.out.println(xml);

        // Creating an Unmarshaller
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        StringReader sr = new StringReader(xml);
        
        Book retr = (Book) jaxbUnmarshaller.unmarshal(sr);
        
        System.out.println("Title: " + retr.getTitle());
        System.out.println("Year : " + retr.getYear());

    }
The output is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <title>Book title</title>
    <year>2010</year>
</book>

Title: Book title
Year : 2010

Pojo to XMLPojo to JSONJAXB to XMLJAXB to JSONJAXB Annotations Tutorial Table Of Content

Friday, 3 August 2012

Parse & Create XML Documents in Java

There are 3 main types of XML parsers available out there: DOM, SAX and StAX. StAX is an improvement on SAX and much easier to use. Therefore, we are not going to cover it here. DOM and StAX offer enough functionalities to work with XML documents.

DOM is a parser building a complete tree of nodes in-memory. This can be an issue when parsing large documents. However, it is the only (and easiest) mean to manipulate documents via CRUD (Create, Read, Update, Delete) operations.

StAX is a pull kind of parser. It parses documents step by step and lets the user pull node elements one by one. It is much more efficient regarding memory consumption, but it cannot be used for CRUD operations.

We will use a maven code sample available here. In the resource directory, there is a rates.xml example file.

DOM

DocumentBuilderFactory factory =
    DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream IS = DOM.class.getResourceAsStream("/rates.xml");
Document doc = builder.parse(IS);

// Retrieving cube XML nodes
NodeList list = doc.getElementsByTagName("Cube");

for (int i = 0; i < list.getLength(); i++) {

  Element element = (Element) list.item(i);

  // Retrieving attributes
  NamedNodeMap attr = element.getAttributes();

  for (int j=0;j<attr.getLength();j++) {
    System.out.print(attr.item(j).getTextContent() + " ");
  }

  System.out.println("");

}
The above code loads the rates.xml file, extracts Cube nodes, and prints their attributes. The output is:
2012-08-02
USD 1.2346
JPY 96.64 
BGN 1.9558 
CZK 25.260
...

StAX

XMLInputFactory inputFactory = XMLInputFactory.newInstance();
InputStream IS = StAX.class.getResourceAsStream("/rates.xml");
XMLEventReader eventReader
  = inputFactory.createXMLEventReader(IS);

// Pulling XML elements
while (eventReader.hasNext()) {

  XMLEvent event = eventReader.nextEvent();

  if (event.isStartElement()) {
    StartElement se = event.asStartElement();

    // Filtering on Cube elements
    if (se.getName().getLocalPart().equals("Cube")) {

      Iterator it = se.getAttributes();
      while (it.hasNext()) {
        Attribute a = (Attribute) it.next();
        System.out.print(a.getValue() + " ");
      }

      event = eventReader.nextEvent();
      System.out.println("");
      continue;

    }

  }

}

The above code pulls XML elements one by one, filters for Cube ones, and prints corresponding attributes. The output is:
2012-08-02
1.2346 USD
96.64 JPY
1.9558 BGN
25.260 CZK
...

CRUD and Print

For creation:
//We need a Document
DocumentBuilderFactory dbfac
    = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();

Element root = doc.createElement("MyXML");
doc.appendChild(root);

Element sub = doc.createElement("MyNode");
sub.setAttribute("MyAttribute", "33");
root.appendChild(sub);

Text text = doc.createTextNode("Some text for my node");
sub.appendChild(text);

Element sub2 = doc.createElement("MyNode2");
sub2.setAttribute("MyAttribute", "45");
root.appendChild(sub2);

Element subnode = doc.createElement("MySubNode");
sub2.appendChild(subnode);

printXML(doc);
The above creates a document with a root node, then adds subnodes, and a subsubnode to the subnode. One also sets some attribute value.

For printing:
TransformerFactory transfac
    = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.INDENT, "yes");

StringWriter sw = new StringWriter();
StreamResult sr = new StreamResult(sw);
DOMSource source = new DOMSource(doc);

trans.transform(source, sr);

String result = sw.toString();
System.out.println(result);
The ident line adds a newline after each node. The output is:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyXML>
<MyNode MyAttribute="33">Some text for my node</MyNode>
<MyNode2 MyAttribute="45">
<MySubNode/>
</MyNode2>
</MyXML>

Pojo to XMLPojo to JSONJAXB to XMLJAXB to JSONJAXB Crash Course