STS搭建Spring MVC 项目

本文介绍如何使用Spring Tool Suite快速创建Spring MVC应用。通过详细步骤展示了从项目搭建到配置文件解析的过程,并介绍了关键组件如Spring Controller及Model的作用。
摘要由CSDN通过智能技术生成

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
<? xml version = "1.0" encoding = "UTF-8" ?>
< project xmlns = "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
<? xml version = "1.0" encoding = "UTF-8" ?>
<! DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
< log4j:configuration xmlns:log4j = "http://jakarta.apache.org/log4j/" >
 
     <!-- Appenders -->
     < appender name = "console" class = "org.apache.log4j.ConsoleAppender" >
         < param name = "Target" value = "System.out" />
         < layout class = "org.apache.log4j.PatternLayout" >
             < param name = "ConversionPattern" value = "%-5p: %c - %m%n" />
         </ layout >
     </ appender >
     
     <!-- Application Loggers -->
     < logger name = "com.journaldev.spring" >
         < level value = "info" />
     </ logger >
     
     <!-- 3rdparty Loggers -->
     < logger name = "org.springframework.core" >
         < level value = "info" />
     </ logger >
     
     < logger name = "org.springframework.beans" >
         < level value = "info" />
     </ logger >
     
     < logger name = "org.springframework.context" >
         < level value = "info" />
     </ logger >
 
     < logger name = "org.springframework.web" >
         < level value = "info" />
     </ logger >
 
     <!-- Root Logger -->
     < root >
         < priority value = "warn" />
         < appender-ref ref = "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
<? 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" >
 
     <!-- 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
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "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
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans:beans xmlns = "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 -->
     < resources mapping = "/resources/**" location = "/resources/" />
 
     <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
     < beans:bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" >
         < beans:property name = "prefix" value = "/WEB-INF/views/" />
         < beans:property name = "suffix" value = ".jsp" />
     </ beans:bean >
     
     < context:component-scan base-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
package com.journaldev.spring;
 
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
/**
  * Handles requests for the application home page.
  */
@Controller
public class HomeController {
     
     private static final Logger logger = LoggerFactory.getLogger(HomeController. class );
     
     /**
      * Simply selects the home view to render by returning its name.
      */
     @RequestMapping (value = "/" , method = RequestMethod.GET)
     public String home(Locale locale, Model model) {
         logger.info( "Welcome home! The client locale is {}." , locale);
         
         Date date = new Date();
         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)
     public String loginPage(Locale locale, Model model) {
         return "login" ;
     }
     
     @RequestMapping (value = "/home" , method = RequestMethod.POST)
     public String login( @Validated User 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
package com.journaldev.spring;
 
public class User {
 
     private String userName;
 
     public String getUserName() {
         return userName;
     }
 
     public void 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"%>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
< title >Login Page</ title >
</ head >
< body >
< form action = "home" method = "post" >
< input type = "text" name = "userName" >< br >
< input type = "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"%>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< meta http-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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值