Saturday, February 11, 2012

Running a spring 2.5 program using Spring STS templates.

As I mentioned, I'm tackling the awkward task of learning Spring 3 via a spring 2.5 book, called Spring Recipes. I managed to get the first program mentioned in Chapter 2, a hello world, running, and I'ld like to share it.

The first thing I did was use Spring's STS templates to generate a utility project. That's file, new, spring template project, spring utility project. I'll give it a name of SpringRecipesHello, and a package name of "com.apress.springrecipes.hello", because that's what's in the book.

Now, we can examine what exactly is generated. Under src/main, we have a couple of classes, ExampleService.java and Service.java.

Service.java is just an interface:

package com.apress.springrecipes.hello;

public interface Service {

String getMessage();

}


ExampleService.java implements the Service:

package com.apress.springrecipes.hello;

import org.springframework.stereotype.Component;


/**
* {@link Service} with hard-coded input data.
*/
@Component
public class ExampleService implements Service {

/**
* Reads next record from input
*/
public String getMessage() {
return "Hello world!";
}

}



You'll notice the "Component" annotation. I'm pretty sure this is telling Spring that this is a java class to be instantiated, and a scan statement in the configuration file will pick it up.

But, how do you run the project?

Well, one way to do is is via the test classes that also get generated. Let's take a look at those.



package com.apress.springrecipes.hello;

import com.apress.springrecipes.hello.ExampleService;
import junit.framework.TestCase;

public class ExampleServiceTests extends TestCase {

private ExampleService service = new ExampleService();

public void testReadOnce() throws Exception {
assertEquals("Hello world!", service.getMessage());
}

}


If we right-click on this and run it as a jUnit test, we'll get a successful test. Disappointingly, it doesn't seem to leverage the spring framework at all - there's no dependency injection.

Let's look at the other test class:


package com.apress.springrecipes.hello;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import com.apress.springrecipes.hello.Service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class ExampleConfigurationTests {

@Autowired
private Service service;

@Test
public void testSimpleProperties() throws Exception {
assertNotNull(service);
}

@Test
public void testReadOnce() throws Exception {
assertEquals("Hello world!", service.getMessage());
}

}


I actually added the second test. The @Autowired seems to indicate that the service should be automatically wired, i.e., instantiated and set, into the "service" member. Adding the second test, which succeeds, shows this to be the case. I didn't have as much luck when I tried changing the other class to include @Autowired - some type of illegal state applicationcontext not loaded error, so - I'll leave it at this for now.

Friday, February 3, 2012

Spring Recipes, for Spring 2.5 - Chapter 1

So, I know this is a little out of date, but I think Spring Recipes for 2. 5 is the best Spring book out there. It doesn't cover 3.0, but you will definitely get the fundamentals down. Plus, I saw a review of the 3.0 book that said it was *huge*, and I really would rather keep things as streamlined a possible. I really want to nail down the fundamentals of Spring.

I previously went through the first five chapters, but it was a while ago and I'm going to do a quick review.

Using a Container

Chapter one talks about containers. You start out simply enough, with a "ReportGenerator" interface that has the method "generate". Generate accepts statistics and generates a report. There are a couple of implementing classes - PdfReportGenerate and HTMLReportGenerator. One of them will print a pdf report, the other will implement an HTML report. All the report service has to do is instantiate whichever of the two it needs, and call "generate" and pass the statistics.

The problem is that, say your product services a couple of different organizations, one likes pdf reports, the other HTML reports. That means you have to go in and muck with your report generator for each different organization. So, really for separation of concerns - you don't want your "what is this organizations type of report" logic mixed in with the "how do I gather statistics" logic, something needs to be done.

You might initially think, well, let's just create a separate class that instantiates the report service, instantiates the concrete report generator class and sets the report generator class on the report service. But, possibly as a scalability issue, they suggest setting up a "container" with a map that holds an instance of the report service, an also an instance of the report generator. So, this generator will hang around with an instance of the report service and the report generator that any old class can grab and use.

So, the report service grabs the report generator from the container whenever it needs it, confident that the correct version of it has been been put in place by the container. Later on, too keep from mucking with the container, you can have the container read a configuration file for the correct report generator class.

But what grabs the report service from the container? Well, the way you would *initially* handle that (we're working our way through all this), is to create the container from a *main* class. The main class then grabs the report generator from the container, and calls something like "createAnnualReport(2007)". The report service will have that method, and will scurry about putting together whatever data it needs to create the annual report. Then, as mentioned earlier, the report service will grab whatever report generator is provided by the container, and call "generate(collected data) on it.

One detail we skimmed over was that when container is created, it puts a static reference to itself (this) into a static variable. This allows the report service to grab the static instance of container from the Container class. Main doesn't need to bother with that when it gets the report service because it instantiated the container.

Whew! That's actually fairly complicated. Just think of the Container as a cupboard full of goodies, which loads itself when instantiated. The main class- the user of the service - happily grabs the reports service from the cupboard (Container) (after instantiating it), and then uses that service.

The service just uses the cupboard (Container) to get *whatever* report generator is there. It gets the that, then calls the report generator method.

Using a Service Locator.

That's all well and good - but what if the cupbard/container varies by organization? Some use one server, some use another, perhaps. If you're writing this framework, do you want to have the code to get the Container (from the report service) vary, depending on how the container is created? According to the book, this could be "complex, proprietary code." Actually, I wish they gave a better example of this problem. It probably has something to do with the fact that it wouldn't make sense for each use of the service to create it's own container - why have a bunch of cupboards (fleeting though they may be) when you can just have one? I'm kind of guessing here, it's a working hypotheses.

So, you've got to look up the cupboard - find it somewhere on the system. Probably that varies depending on the system. And we don't want random services, such as the report service, to have to be responsible for this. It doesn't want to change every time it's on a new system.

So, we separate out the container/cupboard lookup logic into a separate class - the service locator bunny class. This is all about separation of concerns, reducing dependencies, etc. So, instead of having the Report Service grab the report generator directly from the container, we have it do something like "ServiceLocator.getReportGenerator();" And inside the ServiceLocator bunny, it will have method like:

private static Container = Container.instance

and a method which returns the report generator after grabbing it from the cupboard. So, the Service Locator will handle all the work of figuring out where the container is.

Inversion of Control / Dependency Injection

Although we've gotten rid of a specific dependency by providing a container for the Report Service to grab its ReportGenerator from, and even removed the need of the Report Service be concerned about how to implement lookup by giving it a Resource Locater which handles that work - we can make Report Service even dumber. After all, all this was all about was getting the correct instance of the report generator to the report service. So, why not just give report service a setter method for the report generator? No lookup whatsoever in your Report Service! This is good stuff, right?

So, now the container becomes more than just a cupboard. She becomes old Mother Hubbard, giving little Report Service the right instance of the Report Generator and sending her off to school. Mother Hubbard / Container can also now reduce her exposure by no longer providing access to "this".

Note that there are several ways to do injection - setter (via a set method), construction (via - you guessed it - construction) and interface (not widely used).

Adding a Configuration File.

Ok, now that we've set up all these principals, we really ought to make the whole thing configurable. So, what can we configure, and how?

For sure, we can define the pdf or html instance of the report generator. We give it a name that the container can refer to it with, and also the actual class name:

reportGenerator=com.apress.springrecipes.report.PdfReportGenerator

Come to think of it, we can also specify the report service:

reportService=com.apress.springrecipes.report.ReportService

Anything else...hmmm,,,,

Ah - what about which classes get injected where? We gotta let old mother Hubbard, our container/cupboard, know this:

reportService.reportGenerator=reportGenerator

Nice.

Then, the book shows a slick implementation of the Container class. I *think* there might be typo on Dependency Injection part - it seems like "value" should be "parts[1]" on a certain line. I haven't tested it though.

Tuesday, January 17, 2012

Why do you need stripslashes?

I was recently called upon to do an example PHP program. I took a course in it back in 2009, I think, and there are some things I'm a bit fuzzy on. One is when you need to use stripslashes? This blog is an attempt to answer that question.

From

http://php.net/manual/en/function.stripslashes.php

Un-quotes a quoted string.

An example use of stripslashes() is when the PHP directive magic_quotes_gpc is on (it's on by default), and you aren't inserting this data into a place (such as a database) that requires escaping. For example, if you're simply outputting data straight from an HTML form.


This really doesn't clear things up. So, if you get a quotes string - for example 'foo' - you want to end up with foo without the quotes. Then why do they call it stripslashes? Is it because the apostrophes are escaped like so: \', i.e., with a slash? So, does it get rid of the slash *and* the quote?

Ok, here's example 1:



<?php
$str = "Is your name O\'reilly?";

// Outputs: Is your name O'reilly?
echo stripslashes($str);
?>


So, it gets rid of the slash, not the quote. Now the question is, where does the slash come from? I'm assuming it's inserted by a browser, so whatever string it's processing doesn't get mangled.

So, that just leaves the question of why only when your *not* inserting data to a database. And, presumably that's because the string would get mangled if you unescaped it.

Ok, that's it for stripslashes.

Wednesday, January 4, 2012

Good tutorial on maven, spring

Well, our hopes for a quick attack on Spring 3.0 have been somewhat dashed by an apparent bug in the template generation for an MVC app - although we did luckily manage to get one up and running, which I've carefully preserved.

The tutorial did give a pom.xml file at the end - and I'm wondering if it's possible to use a war file generate from that successfully create multiple mvc apps.

Maven is something I've never really had a chance to get into, so I took this as an opportunity to learn a *little* bit about it.

This is a tutorial I landed upon:

http://pookey.co.uk/wordpress/archives/50-getting-started-with-maven-and-spring

I actually got the whole thing to work, start to finish.

The first thing your supposed to do is this command:

mvn archetype:generate --batch-mode \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DgroupId=uk.co.pookey.spring \
-DartifactId=spring-hello \
-Dversion=1.0-SNAPSHOT

When you run it from the command line, get rid of the backslashes and put it all on the same line. It turns out when you run it, because you're specifying the archetype, it's based on some kind of super-pom that specifies a lot of files.

It also creates a source and build file structure, and a program called App.java, which looks like this:


package uk.co.pookey.spring;

public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}


My theory is that the "hello world" app is part of a the arch-type template. So, you just get this nice vanilla directory structure with a hello world app built in.

The directory created gets its name from DartifactId=spring-hello

it also creates a file called pom.xml, as well as src and target directories.

Here's the path of the App.java: src/main/java/uk/co/pookey/spring/App.java

In order to get the App.java to work, you need to add this to your pom.xml:


<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>

<configuration>
<mainClass>uk.co.pookey.spring.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>

This makes this command possible:

mvn exec:java

which will execute the java class.

But first, you need to compile it:


$ mvn compile

Then run:

$ mvn exec:java


It you'll see the "Hello" message.


This is fine for creating a standard product structure, but we're trying to learn a little bit of spring too.

Well, this fine example does that for us. First it specifies in pom.xml a dependency on the spring container:


<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
</dependency>
</dependencies>


I turns out there's a huge, searchable archive of maven dependencies here:

http://www.mvnrepository.com/

But, this is the one where we are getting our version from:

http://www.mvnrepository.com/artifact/org.springframework/spring


This is the strengths of maven - it just knows what the version numbers of the jar files you need are, automatically - since you specified them in the first place. It also pulls down any spring dependencies.

Next we create a new pojo in src/main/java/uk/co/pookey/SayHello.java:

package uk.co.pookey;

public class SayHello
{

private String name;

public void setName(String name)
{
this.name = name;
}

public String getName()
{
return name;
}

public void greet()
{
System.out.println("Hello " + getName());
}

}

This can accept a dependency injection of name, which is printed out later on.

Next we create the famed bean configuration file:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="hello" class="uk.co.pookey.SayHello">
<property name="name" value="Pookey" />
</bean>
</beans>


This is going to be placed in src/main/resources/application-context.xml. You need to create the resources directory.

Finally, we see an example of dependency injection:

package uk.co.pookey.spring;

import uk.co.pookey.SayHello;

i
mport org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;

public class App
{
public static void main( String[] args )
{
BeanFactory factory = new XmlBeanFactory(
new ClassPathResource("application-context.xml"));

SayHello hello = (SayHello) factory.getBean("hello");
hello.greet();
}
}



The app class pulls the the hello bean from the XMLBeanFactory and calls "greet" on it. The factory has already taken care of setting the name to "Pookey" based on the configuration.

Just type "mvn clean compile exec:java" from the directory level of the pom.xml, and you see the "hello, Pookey" result. Nice.

Tuesday, January 3, 2012

Spring 3.0 MVC tutorial - a detailed breakdown - part 1.

I'm having a bit of a problem getting off the blocks with Spring. I've decided to get a simple Spring MVC web app running based on this tutorial:

http://blog.springsource.org/2011/01/04/green-beans-getting-started-with-spring-mvc/

And I got *one* working. But, when I add another, I get a not found and the server shows a mapping error.

So, I'm just going to review the tutorial to see if I can glean any hints from that:

Spring MVC, a part of the core Spring Framework, is a mature and capable action-response style web framework, with a wide range of capabilities and options aimed at handling a variety of UI-focused and non-UI-focused web tier use cases.

All this can potentially be overwhelming to the Spring MVC neophyte. I think it's useful for this audience to show just how little work there is to get a bare Spring MVC application up and running (i.e. consider my example something akin to the world's simplest Spring MVC application), and that's what I'll spend the rest of this article demonstrating.


Off to a good start.


I'm assuming you are familiar with Java, Spring (basic dependency injection concepts), and the basic Servlet programming model, but do not know Spring MVC. After reading this blog entry, readers may continue learning about Spring MVC by looking at Keith Donald's Spring MVC 3 Showcase, or the variety of other online and print resources available that cover Spring and Spring MVC.


I might check out the MVC showcase later on.

A note on dependencies and build systems: this article does not assume that you are using a particular build system, e.g. Maven, Gradle or Ant. A fairly minimal sample Maven POM file is includes as an example at the end of the article.


I badly want to use maven. I can use that on my resume as well.

Spring MVC includes most of the same basic concepts as other so-called web MVC frameworks.

Incoming requests enter the framework via a Front Controller. I

n the case of Spring MVC, this is an actual Java Servlet called DispatcherServlet.


Think of DispatcherServlet as the gatekeeper.

It doesn't perform any real web or business logic, but rather delegates to POJOs called Controllers where the real work is done (either in whole or via the back-end).

When the work has been done, it's the responsibility of Views to produce the output in the proper format (whether that's a JSP page, Velocity template, or JSON response).

Strategies are used to decide which Controller (and which method(s) inside that Controller) handles the request, and which View renders the response.

The Spring container is used to wire together all these pieces. It all looks something like this:






Bootstrapping the DispatcherServlet and Spring Container
As mentioned, all incoming requests flow through a DispatcherServlet.

Like any other Servlet in a Java EE application, we tell the Java EE container to load this Servlet at web app startup time via an in the web app's WEB-INF/web.xml.

The DispatcherServlet is also responsible for loading a Spring ApplicationContext that is used to perform wiring and dependency injection of managed component.

On this basis, we specify some init parameters to the Servlet which configure the Application Context.

Let's look at the config in web.xml:
WEB-INF/web.xml



<?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">

<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>


Ok, there were a couple of important points made. The dispatcher servlet is loaded when the web-app is loaded. This may imply that each app has it's own dispatcher servlet.

This would make sense. each app should have its own front controller. When the request comes into the server, via port 8080, there should be something that lets whatever processes that request know which directory it needs to go to - like the get command parameter. Once it get's there, the DispatcherServlet takes over.


A number of things are being done here:
We register the DispatcherServlet as as a Servlet called appServlet

We map this Servlet to handle incoming requests (relative to the app path) starting with "/"

// the relative to the app path is key. This must be the directory.
// It's actually saying "start looking at the part after the "/"
// It would be good to see an example.


We use the ContextConfigLocation init parameter to customize the location for the base configuration XML file for the Spring Application Context that is loaded by the DispatcherServlet, instead of relying on the default location of -context.xml).



So, this is just telling the server where the spring application context configuration xml file is.


Wait, What if Somebody Doesn't Want to Configure Spring via XML?
The default type of Application Context loaded by the DispatcheServlet expects to load at least on XML file with Spring bean definitions. As you'll see, we'll also enable Spring to load Java-based config, alongside the XML.
Everybody will have their own (sometimes very strong) opinion in this area, but while I generally prefer-Java based configuration, I do believe that smaller amounts of XML config for certain areas can sometimes still make more sense, for one of a number of reasons (e.g. ability to change config without recompilation, conciseness of XML namespaces, toolability, etc.). On this basis, this app will use the hybrid approach, supporting both Java and XML.
Rest assured that if you prefer a pure-Java approach, with no Spring XML at all, it's pretty trivial to achieve, by setting one init param in web.xml to override the default Application Context type and use a variant called AnnotationConfigWebApplicationContext instead.


All this is saying is you can use java-based configurations (how? through annotations?) instead of an xml based one by specifying a param in the web.xml saying the context type is annotation. Then you don't have to specify the path of the spring configuration file.


Here's the controller:

package xyz.sample.baremvc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {

@RequestMapping(value = "/")
public String home() {
System.out.println("HomeController: Passing through...");
return "WEB-INF/views/home.jsp";
}
}



So, this is telling the controller what the view to return is. That's abundantly clear.


Let's walk through the key aspects of this class:
The class has been annotated with the @Controller annotation, indicating that this is a Spring MVC Controller capable of handling web requests. Because @Controller is a specialization of Spring's @Component Stereotype annotation, the class will automatically be detected by the Spring container as part of the container's component scanning process, creating a bean definition and allowing instances to be dependency injected like any other Spring-managed component.

// So, the @Controller annotation means it's going to be a spring-managed bean.

The home method has been annotated with a @RequestMapping annotation, specifying that this method should handle web requests to the path "/", i.e. the home path for the application.

// I guess this means anything with "/" or after. In this case I think maybe
// something like "/baremvc

The home method simply logs a message to system out, and then returns WEB-INF/views/home.jsp, indicating the view which should handle the response, in this case a JSP page. (If hardcoding the entire view path including WEB-INF prefix, and the fact that it's a JSP, seems wrong to you, you are right. We'll deal with this later)

// Ok, that's maybe what I didn't change on the first try




Now, we need to create the view. This JSP page will simply print a greeting.
WEB-INF/views/home.jsp
view sourceprint?
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Hello world!</h1>
</body>


Ok. Next up:


Finally, as previously mentioned, we need to create a minimal Spring Application Context definition file.
WEB-INF/spring/appServlet/servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Scans within the base package of the application for @Components to configure as beans -->
<!-- @Controller, @Service, @Configuration, etc. -->
<context:component-scan base-package="xyz.sample.baremvc" />

<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />

</beans>



Let's examine the contents of this file:
You'll note that a few different Spring XML namespaces are being used: context, mvc, and the default beans
The declaration ensures the Spring container does component scanning, so that any code annotated with @Component subtypes such as @Controller is automatically discovered. You'll note that for efficiency, we limit (to xyz.sample.baremvc in this case) what part of the package space Spring should scan in the classpath


The declaration sets up Spring MVC's support for routing requests to @Controllers, as well as how some things like conversion, formatting and validation are handled (with some sensible defaults based on what (libraries) is present in your classpath, and the ability to override if needed)



Ok, apparently annotation-driven means you can use controllers. Fair enough.

The web app is now ready to run. Assuming the Servlet container (tc Server in my case) is set to listen on localhost:8080, starting the application and then hitting the URL http://localhost:8080/baremvc via our browser results in a display of the expected greeting:




As trivial as it is, running this application involves all the major pieces of a working Spring MVC application. Let's walk through the major sequences and component interactions:

When the web app starts up, the DispatcherServlet is loaded and initialized because of the entry in web.xml.

// right.

The DispatcherServlet loads an annotation-based Application Context, which has been configured to scan for annotated components via a regular expression specifying the base package(s).

// That would've been the entry in the spring context file:

<context:component-scan base-package="xyz.sample.baremvc" />

Annotated components such as the HomeController are detected by the container.

// because of the component-scan command.

The HTTP request to http://localhost:8080/baremvc hits the servlet engine and is routed to our (baremvc) webapp.

The servlet engine of the container. The servlet engine sees the "baremvc" and knows to route it to our web app. Question - which part of the web deployment identifies it as baremvc?


The implicit "/" path at the end of the URL matches the regex that has been registered for the DispatcherServlet, and the request is routed to it

// That's what we saw in web.xml:

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


The DispatcherServlet needs to decide what to do with the request. It uses a strategy called a HandlerAdapter to decide where to route the request. The specific HandlerAdapter type (or types, since they can be chained) to be used can be customized, but by default, an annotation-based strategy is used, which routes requests appropriately to specific methods in classes annotated as @Controller, based on matching criteria in @RequestMapping annotations found in those classes. In this case, the regex on the home method is matched, and it's called to handle the request.

// So, the implicit "/" at the end of the url is mapped by:

@Controller
public class HomeController {

@RequestMapping(value = "/")


The home method does its work, in this case just printing something to system out. It then returns a string that's a hint (in this case, a very explicit one, WEB-INF/views/home.jsp) to help chose the View to render the response.
The DispatcherServlet again relies on a strategy, called a ViewResolver to decide which View is responsible for rendering the response. This can be configured as needed for the application (in a simple or chained fashion), but by default, an InternalResourceViewResolver is used. This is a very simple view resolver that produces a JstlView which simply delegates to the Servlet engine's internal RequestDispatcher to render, and is thus suitable for use with JSP pages or HTML pages.
The Servlet engine renders the response via the specified JSP



Taking It to the Next Level
At this point, we've got an app which certainly qualifies as the world's simplest Spring MVC application, but frankly, doesn't really meet the spirit of that description. Let's evolve things to another level.
As previously mentioned, it's not appropriate to hard-code a path to a view template into a controller, as our controller curretly does. A looser, more logical coupling between controllers and views, with controllers focused on executing some web or business logic, and generally agnostic to specific details like view paths or JSP vs. some other templating technology, is an example of separation of concerns. This allows much greater reuse of both controllers and views, and easier evolution of each in isolation from the other, with possibly different people working on each type of code.
Essentially, the controller code ideally needs to be something like this variant, where a purely logical view name (whether simple or composite) is returned:

//...
@Controller
public class HomeController {

@RequestMapping(value = "/")
public String home() {
System.out.println("HomeController: Passing through...");
return "home";
}
}



This is actually the default of the wizard that using the spring version I downloaded.


Spring MVC's ViewResolver Strategy is actually the mechanism meant to be used to achieve this looser coupling between the controller and the view. As already mentioned, in the absence of the application configuring a specific ViewResolver, Spring MVC sets up a default minimally configured InternalResourceViewResolver, a very simple view resolver that produces a JstlView.

There are potentially other view resolvers we could use, but to get a better level of decoupling, all we actually need to do is set up our own instance of InternalResourceViewResolver with slightly tweaked configuration. InternalResourceViewResolver employs a very simple strategy; it simply takes the view name returned by the controller, and prepends it with an optional prefix (empty by default), and appends it with an optional suffix (empty by default), then feeds that resultant path to a JstlView it creates. The JstlView then delegates to the Servlet engine's RequestDispatcher to do the real work, i.e. rendering the template. Therefore, to allow the controller to return logical view names like home instead of specific view template paths like WEB-INF/views/home.jsp, we simply need to configure this view resolver with the prefix WEB-INF/views and the suffix .jsp, so that it prepends and appends these, respectively, to the logical name returned by the controller.




One easy way to configure the view resolver instance is to introduce the use of Spring's Java-based container configuration, with the resolver as a bean definition:
package xyz.sample.baremvc;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
public class AppConfig {

// Resolve logical view names to .jsp resources in the /WEB-INF/views directory
@Bean
ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}


I get it. He specified a scan in the spring context xml file for the package, the spring will find it and apply it to its configuration. The @Bean tells it to use this method to create a bean.


<!-- Resolve logical view names 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>
It's hard to make a case for this object that one particular approach is much better than the other, so it's really a matter of personal preference in this case (and we can actually see one of the strengths of Spring, its flexible nature).




Ok, this is a good cutoff point before getting into the next part. Btw, to fix the problem - just do a clean.

Monday, January 2, 2012

Arggh! Code sign error - provisioning profile.

Ok, so, today I have to tackle something that cropped up today - a code sign error. I *hate* those. It just is something that is non-intuitive and un-fun.

But, to go along with the new year, I'm adopting a new approach. Slice it up into the tiniest slice of a task possible that will get me toward the solution.

Task one: gather the facts.

What is the problem?

When I try to build my project for archive, I get this unkind error message:

[BEROR]Code Sign error: Provisioning profile '62740BD4-6754-4480-B983-0B85A8FC2D85' can't be found

What led to this?

Well....I was getting an "expiring profile" warning on my project. There are two places in organizer where the profiles are listed. One is in a section called "provisioning profiles".

The other is under "devices".

The difference between them is that if you click on the one above, it will take you to the profiles actual location. The one below, which is apparently connected to the device, won't. It's just a label.

The ones above are the following:

App1 Application Distribution Profile
App2 Development Profile
App2x
TeamProvisioningProfile

The ones connected to my iPond (the provisioning profiles listed for the device) are:

JLPT Vocabulary Quiz Development Profile
JlptVocabQuiz
TeamProvisioningProfile

All of them have expiration dates will in the future.

Now, the *original* problem was that I was getting a warning about an expiring profile. So, I deleted all the profiles which were already expired, or which had nothing to do with this project (I thought), and now I have this error message.

So, my question at this point is - what happened to my friendly distribution profile? I'm not very good about keeping track of where to put these things, all these generated profiles. So, maybe I should just generate another one and reattach it. But how to do that?

So, the question I'm dealing with now is - what's causing this error? It's looking for the provisioning profile, and not finding it, for some reason. I guess I must have deleted it?

These profiles have names. But I'd like to figure out what these names are. I'd especially like to know the one I created. I think it's up on my developer account. Because there is this whole process to generate a certificate request - wait - that's a different thing.

What is the definition of a provisioning profile?

I think we want to get this:

iOS Provisioning Portal

Provision & test your apps on your iPhone, iPad & iPod touch.


Yup, it's the provisioning portal I'm after.

There's a section in there called "provisioning". Inside that, there are lists of development and distribution profiles. Since the problem is happening when I build for archive, my suspicion is that it's the distribution profile.

So, here's what I have for distribution profiles:

JLPT Vocabulary Quiz App Profile id string.com.blah.blah
app id: JLPT Vocabulary Quiz App

1 certificate
1 device



So, very clearly the first one is the distribution profile I use when I distribute the app - although I should have named it something with "distribution" in it.

Now, actually, something to keep in mind is, is the error referring to this provisioning profile? Or is it referring to whatever certificate is being used to sign it? Could this be a certificate issue?

No - the problem is it can't find the provisioning profile.

So, what is the solution? How do it give the provisioning profile? Or do I get rid of the reference in the project to the missing profile?

There's actually a pretty good string of possible solutions here:

http://stackoverflow.com/questions/1760518/codesign-error-provisioning-profile-cannot-be-found-after-deleting-expired-prof


The main one seems to be to edit the project file and get rid of any references to any profiles. But my question is, how to attach the new file?

Ok, when I get into Xcode4, and go into build settings, I can see (under "Target", "Code Signing") under "release", with the confusing "Don't Code Sign" heading, it's listing "iPhone Distribution" which might be one of the ones I deleted, I dunno.

Anyway, I need to figure how to connect my distribution certificate here. First, maybe I'll download it to make sure I'm working with the right one. Then, I will need to figure out how to link it with the app.

Ok, I'm going to download it. The name is JLPT_Vocabulary_Quiz_App_Profile.mobileprovision.

Ok, it just went to downloads. When I double-clicked it, it actually went straight into organizer, the available profiles. Now, let's see if I can specify it in the code signing section.

Sweet! it worked. Nice, I expected to spend 5 or 6 hours on this, it's it's done in 2.5. We like.