You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

advanced-spring.asciidoc 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. ---
  2. title: Vaadin Spring Add-on
  3. order: 18
  4. layout: page
  5. ---
  6. [[advanced.spring]]
  7. = Vaadin Spring Add-on
  8. ((("Vaadin Spring", id="term.advanced.spring.springlong", range="startofrange")))
  9. ((("Spring", id="term.advanced.spring.spring", range="startofrange")))
  10. Vaadin Spring and Vaadin Spring Boot add-ons make it easier to use Spring in
  11. Vaadin applications. Vaadin Spring enables Spring dependency injection with
  12. custom UI and view providers, and provides three custom scopes:
  13. [classname]#UIScope#, [classname]#ViewScope#, and
  14. [classname]#VaadinSessionScope#.
  15. API documentation for add-ons is available at:
  16. * Vaadin Spring API at link:https://vaadin.com/api/vaadin-spring[vaadin.com/api/vaadin-spring]
  17. * Vaadin Spring Boot API at link:https://vaadin.com/api/vaadin-spring-boot[vaadin.com/api/vaadin-spring-boot]
  18. To learn more about Vaadin Spring, the
  19. link:https://vaadin.github.io/spring-tutorial/[Vaadin Spring Tutorial]
  20. gives a hands-on introduction. The source code of the Spring Tutorial demo is
  21. available for browsing or cloning at
  22. link:https://github.com/Vaadin/spring-tutorial[github.com/Vaadin/spring-tutorial].
  23. [[advanced.spring.spring]]
  24. == Spring Overview
  25. __Spring Framework__ is a Java application framework that provides many useful
  26. services for building applications, such as authentication, authorization, data
  27. access, messaging, testing, and so forth. In the Spring core, one of the central
  28. features is dependency injection, which accomplishes inversion of control for
  29. dependency management in managed beans. Other Spring features rely on it
  30. extensively. As such, Spring offers capabilities similar to CDI, but with
  31. integration with other Spring services. Spring is well-suited for applications
  32. where Vaadin provides the UI layer and Spring is used for other aspects of the
  33. application logic.
  34. __Spring Boot__ is a Spring application development tool that allows creating
  35. Spring applications easily. __Vaadin Spring Boot__ builds on Spring Boot to
  36. allow creating Vaadin Spring applications easily. It starts up a servlet,
  37. handles the configuration of the application context, registers a UI provider,
  38. and so forth.
  39. Regarding general Spring topics, we recommend the following Spring
  40. documentation:
  41. ifdef::web[]
  42. * link:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/[Spring
  43. Framework Reference Documentation].
  44. * link:http://projects.spring.io/spring-framework/[Spring Project]
  45. * link:https://vaadin.github.io/spring-tutorial/[Vaadin Spring Tutorial]
  46. endif::web[]
  47. [[advanced.spring.spring.injection]]
  48. === Dependency Injection
  49. __Dependency injection__ is a way to pass dependencies (service objects) to
  50. dependent objects (clients) by injecting them in member variables or initializer
  51. parameters, instead of managing the lifecycle in the clients or passing them
  52. explicitly as parameters. In Spring, injection of a service object to a client
  53. is configured with the [classname]#@Autowired# annotation.
  54. For a very typical example in a web application, you could have a user data
  55. object associated with a user session:
  56. [source, java]
  57. ----
  58. @SpringComponent
  59. @VaadinSessionScope
  60. public class User implements Serializable {
  61. private String name;
  62. public void setName(String name) {this.name = name;}
  63. public String getName() {return name;}
  64. }
  65. ----
  66. The [classname]#@SpringComponent# annotation allows for automatic detection of
  67. managed beans by Spring. (The annotation is exactly the same as the regular
  68. Spring [classname]#@Component#, but has been given an alias, because Vaadin has
  69. a [interfacename]#Component# interface, which can cause trouble.)
  70. Now, if we have a UI view that depends on user data, we could inject the data in
  71. the client as follows:
  72. [source, java]
  73. ----
  74. public class MainView extends CustomComponent implements View {
  75. User user;
  76. Label greeting = new Label();
  77. @Autowired
  78. public MainView(User user) {
  79. this.user = user;
  80. ...
  81. }
  82. ...
  83. @Override
  84. public void enter(ViewChangeEvent event) {
  85. // Then you can use the injected data
  86. // for some purpose
  87. greeting.setValue("Hello, " + user.getName());
  88. }
  89. }
  90. ----
  91. Here, we injected the user object in the constructor. The user object would be
  92. created automatically when the view is created, with all such references
  93. referring to the same shared instance in the scope of the Vaadin user session.
  94. [[advanced.spring.spring.contexts]]
  95. === Contexts and Scopes
  96. __Contexts__ in Spring are services that manage the lifecycle of objects and
  97. handle their injection. Generally speaking, a context is a situation in which an
  98. instance is used with a unique identity. Such objects are essentially
  99. "singletons" in the context. While conventional singletons are application-wide,
  100. objects managed by a Spring container can be "singletons" in a more narrow
  101. __scope__: a user session, a particular UI instance associated with the session,
  102. a view within the UI, or even just a single request. Such a context defines the
  103. lifecycle of the object: its creation, use, and finally its destruction.
  104. Earlier, we introduced a user class defined as session-scoped:
  105. [source, java]
  106. ----
  107. @SpringComponent
  108. @VaadinSessionScope
  109. public class User {
  110. ----
  111. Now, when you need to refer to the user, you can use Spring injection to inject
  112. the session-scoped "singleton" to a member variable or a constructor parameter;
  113. the former in the following:
  114. [source, java]
  115. ----
  116. public class MainView extends CustomComponent implements View {
  117. @Autowired
  118. User user;
  119. Label greeting = new Label();
  120. ...
  121. @Override
  122. public void enter(ViewChangeEvent event) {
  123. greeting.setValue("Hello, " + user.getName());
  124. }
  125. }
  126. ----
  127. [[advanced.spring.boot]]
  128. == Quick Start with Vaadin Spring Boot
  129. The Vaadin Spring Boot is an add-on that allows for easily creating a project
  130. that uses Vaadin Spring. It is meant to be used together with Spring Boot, which
  131. enables general Spring functionalities in a web application.
  132. You can use the Spring Initializr at
  133. link:https://start.spring.io/[start.spring.io] website to generate a project,
  134. which you can then download as a package and import in your IDE. Pick Vaadin as
  135. a dependency on the site to include all the required Vaadin Spring dependencies
  136. and auto-configuration.The generated project is a Spring application stub; you
  137. need to add at least a UI class to the generated project.
  138. See the link:https://vaadin.github.io/spring-tutorial/[Vaadin Spring
  139. Tutorial] for detailed instructions for using Spring Boot.
  140. [[advanced.spring.installation]]
  141. == Installing Vaadin Spring Add-on
  142. Vaadin Spring requires a Java EE 7 compatible servlet container, such as
  143. Glassfish or Apache TomEE Web Profile, as mentioned for the reference toolchain
  144. in
  145. <<dummy/../../../framework/getting-started/getting-started-environment#getting-started.environment,"Setting
  146. up the Development Environment">>.
  147. To install the Vaadin Spring and/or Vaadin Spring Boot add-ons, either define
  148. them as an Ivy or Maven dependency or download from the Vaadin Directory add-on
  149. page at link:https://vaadin.com/directory#addon/vaadin-spring[vaadin.com/directory#addon/vaadin-spring]
  150. or link:https://vaadin.com/directory#addon/vaadin-spring-boot[vaadin.com/directory#addon/vaadin-spring-boot].
  151. See <<dummy/../../../framework/addons/addons-overview.asciidoc#addons.overview,"Using
  152. Vaadin Add-ons">> for general instructions for installing and using Vaadin
  153. add-ons.
  154. The Ivy dependency is as follows:
  155. [subs="normal"]
  156. ----
  157. &lt;dependency org="com.vaadin" name="vaadin-spring"
  158. rev="[replaceable]##latest.release##"/&gt;
  159. ----
  160. The Maven dependency is as follows:
  161. [subs="normal"]
  162. ----
  163. &lt;dependency&gt;
  164. &lt;groupId&gt;com.vaadin&lt;/groupId&gt;
  165. &lt;artifactId&gt;vaadin-spring&lt;/artifactId&gt;
  166. &lt;version&gt;[replaceable]##LATEST##&lt;/version&gt;
  167. &lt;/dependency&gt;
  168. ----
  169. For Vaadin Spring Boot, depending on [literal]#++vaadin-spring-boot-starter++# will
  170. include all the required Vaadin dependencies.
  171. [[advanced.spring.preparing]]
  172. == Preparing Application for Spring
  173. A Vaadin application that uses Spring must have a file named
  174. [filename]#applicationContext.xml# in the [filename]#WEB-INF# directory.
  175. Using Spring Initializr automatically generates a suitable file, but if
  176. you configure Vaadin Spring manually, you can follow the model below.
  177. [subs="verbatim,replacements,quotes"]
  178. ----
  179. &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  180. &lt;beans xmlns="http://www.springframework.org/schema/beans"
  181. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  182. xmlns:context="http://www.springframework.org/schema/context"
  183. xsi:schemaLocation="
  184. http://www.springframework.org/schema/beans
  185. http://www.springframework.org/schema/beans/spring-beans.xsd
  186. http://www.springframework.org/schema/context
  187. http://www.springframework.org/schema/context/spring-context-4.1.xsd"&gt;
  188. &lt;!-- Configuration object --&gt;
  189. &lt;bean class="[replaceable]#com.example.myapp.MySpringUI.MyConfiguration#" /&gt;
  190. &lt;!-- Location for automatically scanned beans --&gt;
  191. &lt;context:component-scan
  192. base-package="[replaceable]#com.example.myapp.domain#" /&gt;
  193. &lt;/beans&gt;
  194. ----
  195. The application should not have a servlet extending [classname]#VaadinServlet#,
  196. as Vaadin servlet has its own [classname]#SpringVaadinServlet# that is deployed
  197. automatically. If you need multiple servlets or need to customize the Vaadin
  198. Spring servlet, see <<advanced.spring.deployment>>.
  199. You can configure managed beans explicitly in the file, or configure them to be
  200. scanned using the annotations, which is the preferred way described in this
  201. section.
  202. [[advanced.spring.springui]]
  203. == Injecting a UI with [classname]#@SpringUI#
  204. ((("[classname]#@SpringUI#", id="term.advanced.spring.springui", range="startofrange")))
  205. Vaadin Spring offers an easier way to instantiate UIs and to define the URL
  206. mapping for them than the usual ways described in
  207. <<dummy/../../../framework/application/application-environment#application.environment,"Deploying
  208. an Application">>. It is also needed for enabling Spring features in the UI. To
  209. define a UI class that should be instantiated for a given URL, you simply need
  210. to annotate the class with [classname]#@SpringUI#. It takes an optional path as
  211. parameter.
  212. [source, java]
  213. ----
  214. @SpringUI(path="/myniceui")
  215. @Theme("valo")
  216. public class MyNiceUI extends UI {
  217. ...
  218. ----
  219. The path in the URL for accessing the UI consists of the context path of the
  220. application and the UI path, for example, [literal]#++/myapp/myniceui++#. Giving
  221. empty UI path maps the UI to the root of the application context, for example,
  222. [literal]#++/myapp++#.
  223. [source, java]
  224. ----
  225. @SpringUI
  226. ----
  227. See <<advanced.spring.deployment>> for how to handle servlet URL mapping of
  228. Spring UIs when working with multiple servlets in the same web application.
  229. (((range="endofrange", startref="term.advanced.spring.springui")))
  230. [[advanced.spring.scopes]]
  231. == Scopes
  232. ((("Spring", "scopes", id="term.advanced.spring.scopes", range="startofrange")))
  233. As in programming languages, where a variable name refers to a unique object
  234. within the scope of the variable, an object has unique identity within a scope
  235. in Spring. However, instead of identifying the objects by variable names, they
  236. are identified by their type (object class) and any qualifiers they may have.
  237. The scope of an object can be defined with an annotation to the class as
  238. follows:
  239. [source, java]
  240. ----
  241. @VaadinSessionScope
  242. public class User {
  243. ...
  244. ----
  245. Defining a scope in Spring is normally done with the [classname]#@Scope#
  246. annotation. For example, [literal]#++@Scope("prototype")++# creates a new
  247. instance every time one is requested/auto-wired. Such standard scopes can be
  248. used with some limitations. For example, Spring session and request scopes do
  249. not work in background threads and with certain push transport modes.
  250. Vaadin Spring provides three scopes useful in Vaadin applications: a session
  251. scope, a UI scope, a view scope, all defined in the
  252. [package]#com.vaadin.spring.annotation# package.
  253. [[advanced.spring.scopes.session]]
  254. === [classname]#@VaadinSessionScope#
  255. The session scope is the broadest of the custom scopes defined in Vaadin Spring.
  256. Objects in the Vaadin session scope are unique in a user session, and shared
  257. between all UIs open in the session. This is the most basic scope in Vaadin
  258. applications, useful for accessing data for the user associated with the
  259. session. It is also useful when updating UIs from a background thread, as in
  260. those cases the UI access is locked on the session and also data should be in
  261. that scope.
  262. [[advanced.spring.scopes.ui]]
  263. === [classname]#@UIScope#
  264. UI-scoped beans are uniquely identified within a UI instance, that is, a browser
  265. window or tab. The lifecycle of UI-scoped beans is bound between the
  266. initialization and closing of a UI. Whenever you inject a bean, as long as you
  267. are within the same UI, you will get the same instance.
  268. Annotating a Spring view (annotated with [classname]#@SpringView# as described
  269. later) also as [classname]#@UIScoped# makes the view retain the same instance
  270. when the user navigates away and back to the view.
  271. [[advanced.spring.scopes.view]]
  272. === [classname]#@ViewScope#
  273. The annotation enables the view scope in a bean. The lifecycle of such a bean
  274. starts when the user navigates to a view referring to the object and ends when
  275. the user navigates out of the view (or when the UI is closed or expires).
  276. Views themselves are by default view-scoped, so a new instance is created every
  277. time the user navigates to the view.
  278. (((range="endofrange", startref="term.advanced.spring.scopes")))
  279. ifdef::web[]
  280. [[advanced.spring.navigation]]
  281. == View Navigation
  282. Vaadin Spring extends the navigation framework in Vaadin, described in
  283. <<dummy/../../../framework/advanced/advanced-navigator#advanced.navigator,"Navigating
  284. in an Application">>. It manages Spring views with a special view provider and
  285. enables view scoping. Furthermore, Vaadin Spring provides a customized navigator class
  286. [classname]#SpringNavigator# that supports the scope functionality.
  287. [[advanced.spring.navigation.ui]]
  288. === Preparing the UI
  289. You can define navigation for any single-component container, component container or bean
  290. implementing [classname]#ViewDisplay#, as described in
  291. <<dummy/../../../framework/advanced/advanced-navigator#advanced.navigator.navigating,"Setting
  292. Up for Navigation">>, but typically you set up navigation for the entire UI
  293. content. The easiest way to set up navigation is to use the annotation
  294. [classname]#@SpringViewDisplay# on the UI (in which case the whole contents of the UI are
  295. replaced on navigation) or on any UI scoped bean implementing one of the above mentioned
  296. interfaces.
  297. [source, java]
  298. ----
  299. @SpringUI(path="/myspringui")
  300. @SpringViewDisplay
  301. public class MySpringUI extends UI {
  302. @Override
  303. protected void init(VaadinRequest request) {
  304. }
  305. }
  306. ----
  307. If not using Spring Boot, auto-configuration of navigation can be enabled with the annotation
  308. @EnableVaadinNavigation on a configuration class.
  309. [[advanced.spring.navigation.view]]
  310. === The View
  311. A view managed by Vaadin Spring only needs to have the [classname]#@SpringView#
  312. annotation, which registers the view in the [classname]#SpringViewProvider#. The
  313. annotation is also necessary to enable Spring features in the view, such as
  314. injection.
  315. [source, java]
  316. ----
  317. @SpringView(name=MainView.NAME)
  318. public class MainView extends CustomComponent implements View {
  319. public static final String NAME = "main";
  320. ...
  321. ----
  322. The annotation can have the following optional paramers:
  323. name (optional):: Specifies the path by which the view can be accessed programmatically and by the
  324. URI fragment.
  325. +
  326. [source, java]
  327. ----
  328. @SpringView(name="main")
  329. ----
  330. +
  331. If the view name is not given, it is derived from the class name by removing a
  332. possible "View" suffix, making it lower case, and using a dash ("-") to separate
  333. words originally denoted by capital letters. Thereby, a view class such as
  334. [classname]#MyFunnyView# would have name " [literal]#++my-funny++#".
  335. +
  336. It is a recommended pattern to have the view name in a static member constant in
  337. the view class, as was done in the example previously, so that the name can be
  338. referred to safely.
  339. +
  340. You can also navigate to a view with a URI fragment such as
  341. [literal]#++#!myview/someparameter++# or programmatically with:
  342. +
  343. [source, java]
  344. ----
  345. getUI().getNavigator().navigateTo("myview/someparameter");
  346. ----
  347. +
  348. The [methodname]#enter()# method of the view gets the URI fragment as parameter
  349. as is and can interpret it in any application-defined way.
  350. uis:: If the application has multiple UIs that use [classname]#SpringViewProvider#,
  351. you can use this parameter to specify which UIs can show the view.
  352. +
  353. [source, java]
  354. ----
  355. @SpringView(name="myview", uis={MySpringUI.class})
  356. ----
  357. +
  358. If the list contains [parameter]#UI.class#, the view is available to all UIs.
  359. +
  360. [source, java]
  361. ----
  362. @SpringView(name="myview", uis={UI.class})
  363. ----
  364. In the following, we have a login view that accesses a session-scoped user
  365. object. Here, we use a constant to define the view name, so that we can use the
  366. constant when navigating to it.
  367. [source, java]
  368. ----
  369. @SpringView(name=LoginView.NAME)
  370. public class LoginView extends CustomComponent
  371. implements View {
  372. public final static String NAME = "";
  373. // Here we inject to the constructor and actually do
  374. // not store the injected object to use it later
  375. @Autowired
  376. public LoginView(User user) {
  377. VerticalLayout layout = new VerticalLayout();
  378. // An input field for editing injected data
  379. BeanItem<User> item = new BeanItem<User>(user);
  380. TextField username = new TextField("User name",
  381. item.getItemProperty("name"));
  382. username.setNullRepresentation("");
  383. layout.addComponent(username);
  384. // Login button (authentication omitted) / Java 8
  385. layout.addComponent(new Button("Login", e ->
  386. getUI().getNavigator().
  387. navigateTo(MainView.VIEWNAME)));
  388. setCompositionRoot(layout);
  389. }
  390. @Override
  391. public void enter(ViewChangeEvent event) {}
  392. }
  393. ----
  394. You could now navigate to the view from any other view in the UI with:
  395. [source, java]
  396. ----
  397. getUI().getNavigator().navigateTo(LoginView.VIEWNAME);
  398. ----
  399. endif::web[]
  400. [[advanced.spring.accesscontrol]]
  401. == Access Control
  402. Access control for views can be implemented by registering beans implementing
  403. [interfacename]#ViewAccessControl# or
  404. [interfacename]#ViewInstanceAccessControl#, which can restrict access to the
  405. view either before or after a view instance is created.
  406. Integration with authorization solutions, such as Spring Security, is provided
  407. by additional unofficial add-ons on top of Vaadin Spring.
  408. [[advanced.spring.accesscontrol.accessdenied]]
  409. === Access Denied View
  410. If access to a view is denied by an access control bean, the access denied view
  411. is shown for it. For non-existing views, the error view is shown. You can set
  412. up an "Access Denied" view that is shown if the access is denied with
  413. [methodname]#setAccessDeniedViewClass()# in [classname]#SpringViewProvider#,
  414. and an error view with [methodname]#setErrorView()# in [classname]#SpringNavigator#.
  415. The same view can also be used both as an access denied view and as an error
  416. view to hide the existence of views the user is not allowed to access.
  417. [source, java]
  418. ----
  419. @Autowired
  420. SpringViewProvider viewProvider;
  421. @Autowired
  422. SpringNavigator navigator;
  423. @Override
  424. protected void init(VaadinRequest request) {
  425. // Set up access denied view
  426. viewProvider.setAccessDeniedViewClass(
  427. MyAccessDeniedView.class);
  428. // Set up error view
  429. navigator.setErrorView(MyErrorView.class);
  430. ----
  431. Note that the error view can also be a class with which an error view bean is
  432. found. In this case, the error view must be UI scoped.
  433. [[advanced.spring.deployment]]
  434. == Deploying Spring UIs and Servlets
  435. Vaadin Spring hooks into Vaadin framework by using a special
  436. [classname]#SpringVaadinServlet#. As described earlier, you do not need to map
  437. an URL path to a UI, as it is handled by Vaadin Spring. However, in the
  438. following, we go through some cases where you need to customize the servlet or
  439. use Spring with non-Spring servlets and UIs in a web application.
  440. [[advanced.spring.servlets.custom]]
  441. === Custom Servlets
  442. When customizing the Vaadin servlet, as outlined in
  443. <<dummy/../../../framework/application/application-lifecycle#application.lifecycle.servlet-service,"Vaadin
  444. Servlet, Portlet, and Service">>, you simply need to extend
  445. [classname]#com.vaadin.spring.server.SpringVaadinServlet# instead of
  446. [classname]#com.vaadin.servlet.VaadinServlet#.
  447. [subs="normal"]
  448. ----
  449. @WebServlet(value = "[replaceable]#/*#", asyncSupported = true)
  450. public class [replaceable]#MySpringServlet# extends SpringVaadinServlet {
  451. }
  452. ----
  453. The custom servlet must not have [classname]#@VaadinServletConfiguration#, as
  454. you would normally with a Vaadin servlet, as described in
  455. <<dummy/../../../framework/application/application-environment#application.environment,"Deploying
  456. an Application">>.
  457. [[advanced.spring.deployment.urlmapping]]
  458. === Defining Servlet Root
  459. Spring UIs are managed by a Spring servlet ( [classname]#SpringVaadinServlet#),
  460. which is by default mapped to the root of the application context. For example,
  461. if the name of a Spring UI is " [literal]#++my-spring-ui++#" and application
  462. context is [literal]#++/myproject++#, the UI would by default have URL "
  463. [literal]#++/myproject/my-spring-ui++#". If you do not want to have the servlet
  464. mapped to context root, you can use a [classname]#@WebServlet# annotation for
  465. the servlet or a [filename]#web.xml# definition to map all Spring UIs to a
  466. sub-path.
  467. For example, if we have a root UI and another:
  468. [subs="normal"]
  469. ----
  470. @SpringUI(path=[replaceable]#""#) // At Spring servlet root
  471. public class [replaceable]#MySpringRootUI# extends UI {...}
  472. @SpringUI("[replaceable]#another#")
  473. public class [replaceable]#AnotherUI# extends UI {...}
  474. ----
  475. Then define a path for the servlet by defining a custom servlet:
  476. [subs="normal"]
  477. ----
  478. @WebServlet(value = "[replaceable]#/myspringuis/*#", asyncSupported = true)
  479. public class [replaceable]#MySpringServlet# extends SpringVaadinServlet {
  480. }
  481. ----
  482. These two UIs would have URLs /myproject/myspringuis and
  483. /myproject/myspringuis/another, respectively.
  484. You can also map the Spring servlet to another URL in servlet definition in
  485. [filename]#web.xml#, as described the following.
  486. [[advanced.spring.servlets.mixing]]
  487. === Mixing With Other Servlets
  488. The [classname]#SpringVaadinServlet# is normally used as the default servlet,
  489. but if you have other servlets in the application, such as for non-Spring UIs,
  490. you need to define the Spring servlet explicitly in the [filename]#web.xml#. You
  491. can map the servlet to any URL path, but perhaps typically, you define it as the
  492. default servlet as follows, and map the other servlets to other URL paths:
  493. [subs="normal"]
  494. ----
  495. &lt;web-app&gt;
  496. ...
  497. &lt;servlet&gt;
  498. &lt;servlet-name&gt;Default&lt;/servlet-name&gt;
  499. &lt;servlet-class&gt;
  500. com.vaadin.spring.server.SpringVaadinServlet
  501. &lt;/servlet-class&gt;
  502. &lt;/servlet&gt;
  503. &lt;servlet-mapping&gt;
  504. &lt;servlet-name&gt;Default&lt;/servlet-name&gt;
  505. &lt;url-pattern&gt;[replaceable]##/myspringuis/*##&lt;/url-pattern&gt;
  506. &lt;/servlet-mapping&gt;
  507. &lt;servlet-mapping&gt;
  508. &lt;servlet-name&gt;Default&lt;/servlet-name&gt;
  509. &lt;url-pattern&gt;/VAADIN/+++*+++&lt;/url-pattern&gt;
  510. &lt;/servlet-mapping&gt;
  511. &lt;/web-app&gt;
  512. ----
  513. With such a setting, paths to Spring UIs would have base path [filename]#/myapp/myspringuis#, to which the (optional) UI path would be appended.
  514. The [filename]#/VAADIN/*# only needs to be mapped to the servlet if there are no other Vaadin servlets.
  515. (((range="endofrange", startref="term.advanced.spring.springlong")))
  516. (((range="endofrange", startref="term.advanced.spring.spring")))