STS搭建Spring MVC 项目

来源:互联网 发布:开淘宝店邮费 编辑:程序博客网 时间:2024/04/30 04:14

Spring MVC Tutorial for Beginners with Spring Tool Suite

详情请看原文:http://www.journaldev.com/2433/spring-mvc-tutorial-for-beginners-with-spring-tool-suite

Spring MVC framework is widely used for java web applications. Just like Struts Framework, Spring MVC is also based on Java EE Servlet and JSP technologies and implement ModelViewController design pattern.

We have earlier seen how Spring Dependency Injection works and in this tutorial we will learn how to create a simple web application using Spring MVC framework.

We can use Eclipse or IntelliJ IDE for the Spring projects development, but SpringSource provides Spring Tool Suite (STS) that is an IDE based on Eclipse and comes with in-built VMware vFabric tc Server that is built on top of Apache Tomcat container and optimized for Spring based applications.

I would use STS for this tutorial and other future tutorials because it makes a developers life easier by providing following features:

  • Support for creating skeletal Spring applications (MVC, Rest, Batch etc), good for starting project from scratch.
  • Provides useful features such as creating Spring Configuration files, parsing config files and classes to provide useful information about them.
  • Automatic validation of Spring application
  • Refactoring support to easily make project changes, the changes gets reflected in config files too.
  • Code assist for not only classes but configuration files too, I like this feature a lot because most of the times we need to know what we can use and it’s details.
  • Best support for Aspect Oriented Programming (AOP) through integration of AspectJ.

Looking at all the features STS provide, I was sold for this and decided to use it for Spring application and till now I am very happy with it.

Just Download the STS from STS Official Download Page and install it. I am using STS 3.4.0.RELEASE that is based on Eclipse 4.3.1 release.

Spring-Tool-Suite

If you don’t want to use STS and want to get it’s facilities in existing Eclipse, then you need to install it’s plugin from Eclipse Marketplace. Use below image as reference and make sure to chose the correct STS version for installation. Below plugin is good for Eclipse Kepler.

Spring-Tool-Suite-Eclipse

If you don’t want to use SpringSource server, you can deploy the application in any other Java EE container such as Tomcat, JBoss etc. For this tutorial, I will use the server that ships with STS but I have tested the application by exporting it as WAR file into separate tomcat server and it’s working fine.

Now that our server environment and IDE is ready, let’s proceed to create our first Spring MVC project. Below steps are valid for STS as well as Eclipse with STS plugins.

Creating Spring MVC Application in STS or Eclipse

Step 1: Create New Spring Project from the menu.

Spring-Project-New

Step 2: In the new project window, give name as “SpringMVCExample” and chose template as “Spring MVC Project”. If you are using this template for the first time, STS will download it from SpringSource website. If you want, you can add the project to any working set.

Spring-New-MVC-Project-Template

Spring-MVC-Template-Download

Step 3: When the template is downloaded, in next screen you need to provide the top-level package name. This package will be used as the base-package for Spring components.

Spring-MVC-source-Package

Step 4: Once the project is created by Spring MVC template, it will look like below image.

Spring-MVC-STS-Project

Don’t worry if you don’t see User.java class, login.jsp and user.jsp files, they have been added by me later on.

If your project is not compiled and you see some errors, run Maven/Update Project. Make sure to check the “Force update of Snapshots/Releases” options, refer below image.

Maven-Force-update-projects

Overall project looks just like any other maven based web application with some Spring configuration files. Now it’s time to analyze the different part of the projects and extend it a little.

Spring Dependencies

Our generated pom.xml file looks like below.

pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.journaldev</groupId>
    <artifactId>SpringMVCExample</artifactId>
    <name>SpringMVCExample</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>
    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>4.0.0.RELEASE</org.springframework-version>
        <org.aspectj-version>1.7.4</org.aspectj-version>
        <org.slf4j-version>1.7.5</org.slf4j-version>
    </properties>
    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
                 
        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>
         
        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>
 
        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
                 
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
     
        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>       
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

artifactId will be the servlet-context for the web application, so you can change it if you want something else.

There are few properties defined for Spring Framework, AspectJ and SLF4j versions, I found that they were not reflecting the latest versions, so I have changed them to the latest stable version as of today.

The project dependencies that I am interested in are;

  • spring-context: Spring Core dependency. Notice the exclusion of commons logging in favor of SLF4J.
  • spring-webmvc: Spring artifact for MVC support
  • aspectjrt: AspectJ API reference
  • SLF4J and Log4j: For logging purposes, Spring is very easy to configure for log4j or Java Logging APIbecause of SLF4J integration.
  • javax.inject – JSR330 API for dependency injection

There are some other dependencies added, such as Servlet, JSP, JSTL and JUnit API but for starter application, we can overlook them.

Log4j Configuration

Generated log4j.xml file looks like below.

log4j.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPElog4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/">
 
    <!-- Appenders -->
    <appendername="console"class="org.apache.log4j.ConsoleAppender">
        <paramname="Target"value="System.out"/>
        <layoutclass="org.apache.log4j.PatternLayout">
            <paramname="ConversionPattern"value="%-5p: %c - %m%n" />
        </layout>
    </appender>
     
    <!-- Application Loggers -->
    <loggername="com.journaldev.spring">
        <levelvalue="info"/>
    </logger>
     
    <!-- 3rdparty Loggers -->
    <loggername="org.springframework.core">
        <levelvalue="info"/>
    </logger>
     
    <loggername="org.springframework.beans">
        <levelvalue="info"/>
    </logger>
     
    <loggername="org.springframework.context">
        <levelvalue="info"/>
    </logger>
 
    <loggername="org.springframework.web">
        <levelvalue="info"/>
    </logger>
 
    <!-- Root Logger -->
    <root>
        <priorityvalue="warn"/>
        <appender-refref="console"/>
    </root>
     
</log4j:configuration>

Notice that it’s printing everything to console, we can easily add appenders to redirect logging to files.

Deployment Descriptor Configuration

Let’s see our web.xml and analyze it.

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xmlversion="1.0"encoding="UTF-8"?>
<web-appversion="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">
 
    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
     
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- 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>

ContextLoaderListener ties the ApplicationContext lifecycle to ServletContext lifecycle and automate the creation of ApplicationContextApplicationContext is the place for Spring beans and we can provide it’s configuration through contextConfigLocation context parameter. root-context.xml file provides the configuration details for WebApplicationContext.

DispatcherServlet is the controller class for Spring MVC application and all the client requests is getting handled by this servlet. The configuration are being loaded from servlet-context.xml file.

Spring Configuration Files

root-context.xml
1
2
3
4
5
6
7
8
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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.xsd">
     
    <!-- Root Context: defines shared resources visible to all other web components -->
         
</beans>

We can define shared beans here, as of now there is nothing in it.

servlet-context.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xmlversion="1.0"encoding="UTF-8"?>
<beans:beansxmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
     
    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven/>
 
    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resourcesmapping="/resources/**"location="/resources/"/>
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:propertyname="prefix"value="/WEB-INF/views/"/>
        <beans:propertyname="suffix"value=".jsp"/>
    </beans:bean>
     
    <context:component-scanbase-package="com.journaldev.spring"/>  
     
</beans:beans>

This is how the standard Spring configuration file looks like, just imagine writing all this on your own and you will start liking STS tool.

annotation-driven element is used to let Controller servlet know that annotations will be used for bean configurations.

resources element defines the location where we can put static files such as images, html pages etc that we don’t want to get through Spring framework.

InternalResourceViewResolver is the view resolver, we can provide view pages location through prefix and suffix properties. So all our JSP pages should be in /WEB-INF/views/ directory.

context:component-scan element is used to provide the base-package location for scanning Controller classes. Remember the value of top-level package given at the time of project creation, it’s the same value getting used here.

Spring Controller Class

HelloController is created automatically with the home() method, although I have extended it little bit by adding loginPage() and login() methods.

HomeController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
packagecom.journaldev.spring;
 
importjava.text.DateFormat;
importjava.util.Date;
importjava.util.Locale;
 
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.stereotype.Controller;
importorg.springframework.ui.Model;
importorg.springframework.validation.annotation.Validated;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestMethod;
 
/**
 * Handles requests for the application home page.
 */
@Controller
publicclass HomeController {
     
    privatestatic final Logger logger = LoggerFactory.getLogger(HomeController.class);
     
    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    publicString home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
         
        Date date = newDate();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
         
        String formattedDate = dateFormat.format(date);
         
        model.addAttribute("serverTime", formattedDate );
         
        return"home";
    }
     
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    publicString loginPage(Locale locale, Model model) {
        return"login";
    }
     
    @RequestMapping(value = "/home", method = RequestMethod.POST)
    publicString login(@ValidatedUser user, Model model) {
        model.addAttribute("userName", user.getUserName());
        return"user";
    }
}

@Controller annotation is used to indicate that it’s a web controller class.

@RequestMapping is used with classes and methods to redirect client request to specific handler method. Notice that handler methods are returning String, this should be the name of view page to be used as response.

As you can see that we are having three methods returning different strings, so we need to create JSP pages with same name.

Notice that login() method will get called with HTTP method as POST, so we are expecting some form data here. So we have User model class and it’s marked for validation using @Validated annotation.

Every method contains Model as argument and we can set attributes to be later used in the JSP response pages.

Model Classes

Model classes are used to hold form variables, our User model bean looks like below.

User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
packagecom.journaldev.spring;
 
publicclass User {
 
    privateString userName;
 
    publicString getUserName() {
        returnuserName;
    }
 
    publicvoid setUserName(String userName) {
        this.userName = userName;
    }
     
}

A simple java bean with variable name and it’s getter and setter methods.

View Pages

We have three JSP pages like below.

home.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ 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>
 
<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

Notice the use of JSP Expression Language to get the attribute values.

login.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPEhtml PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
<formaction="home"method="post">
<inputtype="text"name="userName"><br>
<inputtype="submit"value="Login">
</form>
</body>
</html>

A simple JSP page for user to provide the userName as input. Notice that form variable name is same as User class variable name. Also form action is “home” and method is “post”. It’s clear that HomeController login() method will handle this request.

user.jsp
1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPEhtml PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
<title>User Home Page</title>
</head>
<body>
<h3>Hi ${userName}</h3>
</body>
</html>

Simple home page for user where username is displayed, notice that we are setting this attribute in the login method.

Running Spring MVC Application

Our application is ready for execution, just run it on the VMware tc Server or your choice of any other servlet container, you will get below pages as response.

Spring-MVC-HelloWorld

Spring-MVC-HelloWorld-GET

Spring-MVC-HelloWorld-POST

That’s it, you can see that how easy it is to create Spring MVC application using STS plugins. The code size is very less and most of the configuration is handled by Spring so that we can focus on business logic. Download project from below link and play around with it.

Download Spring MVC Project4742 downloads
0 0
原创粉丝点击