[ 
https://issues.apache.org/jira/browse/WW-5791?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Lukasz Lenart updated WW-5791:
------------------------------
    Description: 
h2. Goal

Give newcomers a working Struts application with almost no setup: add one 
dependency, write an action class, run {{main()}}, see the page. No 
{{web.xml}}, no {{struts.xml}}, no external servlet container. Standalone — no 
Spring dependency, no changes to core.

h2. Scope
* New {{struts2-boot-starter}} artifact (module {{boot/}}, listed in the BOM) 
pulling in core and embedded Tomcat, registering 
{{StrutsPrepareAndExecuteFilter}} in code. Tomcat follows core's Jakarta line: 
10.1 by default, 11 under {{-Pjakartaee11}}.
* {{StrutsBoot.run(App.class, args)}} entry point (blocks); 
{{StrutsBoot.start(...)}} returns a closeable server handle for tests. The 
application class implements {{StrutsBootApplication}}.
* Fluent action registration, fed into the configuration through a 
{{ConfigurationProvider}} hooked in via the existing {{configProviders}} filter 
init parameter. No Convention plugin, no classpath scanning.

{code:java}public class HelloApp implements StrutsBootApplication {

    public static void main(String[] args) {
        StrutsBoot.run(HelloApp.class, args);
    }

    @Override
    public void actions(ActionRegistry actions) {
        actions.action("hello", HelloAction.class)
               .success("hello.ftl");

        actions.namespace("/admin", admin -> {
            admin.action("users", UserAction.class)
                 .method("list")
                 .success("admin/users.ftl");

            admin.action("saveUser", UserAction.class)
                 .method("save")
                 .httpMethods(POST)
                 .result("input", "admin/userForm.ftl")
                 .redirectAction("success", "users");
        });
    }
}
{code}
* Defaults: each namespace is a package extending {{struts-default}}; top level 
is namespace {{""}}; {{method}} defaults to {{execute}}; {{success(path)}} is 
shorthand for {{result("success", path)}}; interceptors default to 
{{defaultStack}}, overridable per action or namespace by stack name; 
{{httpMethods(...)}} maps to the http-method restriction from WW-3717.
* Registry config is never broader than the equivalent {{struts.xml}}: Strict 
Method Invocation stays on, action classes go into the OGNL allowlist like 
XML-declared ones, and each action allows only its registered method.
* Views: FreeMarker only, chosen by {{.ftl}} extension, resolved from 
{{classpath:/templates/}}.
* Startup fails with a {{ConfigurationException}} for: slashes in action names 
(use namespaces), non-{{.ftl}} views, missing templates, unknown interceptor 
stacks, non-public action classes or ones without a public no-arg constructor, 
and duplicate actions in the same namespace (within the registry or against 
{{struts.xml}}).
* Configuration: the existing {{struts.properties}}; Boot settings 
{{struts.boot.port}} (default 8080), {{struts.boot.address}} (default: all 
interfaces) and {{struts.boot.context-path}} (default empty), overridable by 
{{--key=value}} arguments. Not {{application.properties}}, to avoid clashing 
with Spring Boot.
* Container defaults: error pages carry no stack trace or server version; 
{{DefaultServlet}} serves only an empty per-run docBase; Tomcat's base 
directory is a fresh temp directory deleted on shutdown; {{devMode}} is never 
switched on.
* A {{struts.xml}} on the classpath is still loaded alongside the registry.
* Example app {{apps/boot-hello}}, shaded into a runnable jar with 
{{maven-shade-plugin}}; not deployed to Maven Central.
* {{THREAT_MODEL.md}} gains a Boot section: the starter's container defaults 
are in model.

h2. Parked for later
* Running an existing Struts WAR as a self-contained jar (migration path).
* JSP views in the embedded container.
* Gradle plugin.
* Alternative containers (Jetty, Undertow).
* Fluent definition of custom interceptor stacks.
* Global results, global exception mappings, wildcard actions in the registry.
* Optional bridge to Convention plugin annotations.
* Dev-mode reload of templates and registry.
* Project generator / quick-start archetype.
* Health and info endpoints.
* A dedicated Maven plugin or nested-jar launcher, needed before plugins can be 
used in Boot apps (shading overwrites duplicate {{struts-plugin.xml}} files).

  was:
h2. Goal

Give newcomers a working Struts application with almost no setup: add one 
dependency, write an action class, run {{main()}}, see the page. No 
{{web.xml}}, no {{struts.xml}}, no external servlet container. Standalone — no 
Spring dependency.

h2. Minimal scope
* New {{struts-boot-starter}} artifact pulling in core and an embedded servlet 
container (Tomcat), registering {{StrutsPrepareAndExecuteFilter}} in code.
* {{StrutsBoot.run(App.class, args)}} entry point; the application class 
implements {{StrutsBootApplication}}.
* Fluent action registration, fed into the configuration through a single 
{{ConfigurationProvider}} built on {{PackageConfig}} / {{ActionConfig}} / 
{{ResultConfig}} builders. No Convention plugin, no classpath scanning.

{code:java}public class HelloApp implements StrutsBootApplication {

    public static void main(String[] args) {
        StrutsBoot.run(HelloApp.class, args);
    }

    @Override
    public void actions(ActionRegistry actions) {
        actions.action("hello", HelloAction.class)
               .success("hello.ftl");

        actions.namespace("/admin", admin -> {
            admin.action("users", UserAction.class)
                 .method("list")
                 .success("admin/users.ftl");

            admin.action("saveUser", UserAction.class)
                 .method("save")
                 .httpMethods(POST)
                 .result("input", "admin/userForm.ftl")
                 .redirectAction("success", "users");
        });
    }
}
{code}
* Defaults: each namespace is a package extending {{struts-default}}; top level 
is namespace {{""}}; {{method}} defaults to {{execute}}; {{success(path)}} is 
shorthand for {{result("success", path)}}; interceptors default to 
{{defaultStack}}, overridable per action or namespace by stack name; 
{{httpMethods(...)}} maps to the http-method restriction from WW-3717.
* Views: FreeMarker only, chosen by {{.ftl}} extension, resolved from 
{{classpath:/templates/}}.
* Configuration: the existing {{struts.properties}}; Boot-only settings (port, 
context path) under a {{struts.boot.*}} prefix. Not {{application.properties}}, 
to avoid clashing with Spring Boot.
* A {{struts.xml}} on the classpath is still loaded alongside the registry.
* Runnable fat jar via a Maven plugin.

h2. Parked for later
* Running an existing Struts WAR as a self-contained jar (migration path).
* JSP views in the embedded container.
* Gradle plugin.
* Alternative containers (Jetty, Undertow).
* Fluent definition of custom interceptor stacks.
* Global results, global exception mappings, wildcard actions in the registry.
* Optional bridge to Convention plugin annotations.
* Dev-mode reload of templates and registry.
* Project generator / quick-start archetype.
* Health and info endpoints.


> Struts Boot: run a Struts application from main() with an embedded container 
> and programmatic action registration
> -----------------------------------------------------------------------------------------------------------------
>
>                 Key: WW-5791
>                 URL: https://issues.apache.org/jira/browse/WW-5791
>             Project: Struts 2
>          Issue Type: New Feature
>          Components: Core
>            Reporter: Lukasz Lenart
>            Assignee: Lukasz Lenart
>            Priority: Major
>             Fix For: 7.5.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> h2. Goal
> Give newcomers a working Struts application with almost no setup: add one 
> dependency, write an action class, run {{main()}}, see the page. No 
> {{web.xml}}, no {{struts.xml}}, no external servlet container. Standalone — 
> no Spring dependency, no changes to core.
> h2. Scope
> * New {{struts2-boot-starter}} artifact (module {{boot/}}, listed in the BOM) 
> pulling in core and embedded Tomcat, registering 
> {{StrutsPrepareAndExecuteFilter}} in code. Tomcat follows core's Jakarta 
> line: 10.1 by default, 11 under {{-Pjakartaee11}}.
> * {{StrutsBoot.run(App.class, args)}} entry point (blocks); 
> {{StrutsBoot.start(...)}} returns a closeable server handle for tests. The 
> application class implements {{StrutsBootApplication}}.
> * Fluent action registration, fed into the configuration through a 
> {{ConfigurationProvider}} hooked in via the existing {{configProviders}} 
> filter init parameter. No Convention plugin, no classpath scanning.
> {code:java}public class HelloApp implements StrutsBootApplication {
>     public static void main(String[] args) {
>         StrutsBoot.run(HelloApp.class, args);
>     }
>     @Override
>     public void actions(ActionRegistry actions) {
>         actions.action("hello", HelloAction.class)
>                .success("hello.ftl");
>         actions.namespace("/admin", admin -> {
>             admin.action("users", UserAction.class)
>                  .method("list")
>                  .success("admin/users.ftl");
>             admin.action("saveUser", UserAction.class)
>                  .method("save")
>                  .httpMethods(POST)
>                  .result("input", "admin/userForm.ftl")
>                  .redirectAction("success", "users");
>         });
>     }
> }
> {code}
> * Defaults: each namespace is a package extending {{struts-default}}; top 
> level is namespace {{""}}; {{method}} defaults to {{execute}}; 
> {{success(path)}} is shorthand for {{result("success", path)}}; interceptors 
> default to {{defaultStack}}, overridable per action or namespace by stack 
> name; {{httpMethods(...)}} maps to the http-method restriction from WW-3717.
> * Registry config is never broader than the equivalent {{struts.xml}}: Strict 
> Method Invocation stays on, action classes go into the OGNL allowlist like 
> XML-declared ones, and each action allows only its registered method.
> * Views: FreeMarker only, chosen by {{.ftl}} extension, resolved from 
> {{classpath:/templates/}}.
> * Startup fails with a {{ConfigurationException}} for: slashes in action 
> names (use namespaces), non-{{.ftl}} views, missing templates, unknown 
> interceptor stacks, non-public action classes or ones without a public no-arg 
> constructor, and duplicate actions in the same namespace (within the registry 
> or against {{struts.xml}}).
> * Configuration: the existing {{struts.properties}}; Boot settings 
> {{struts.boot.port}} (default 8080), {{struts.boot.address}} (default: all 
> interfaces) and {{struts.boot.context-path}} (default empty), overridable by 
> {{--key=value}} arguments. Not {{application.properties}}, to avoid clashing 
> with Spring Boot.
> * Container defaults: error pages carry no stack trace or server version; 
> {{DefaultServlet}} serves only an empty per-run docBase; Tomcat's base 
> directory is a fresh temp directory deleted on shutdown; {{devMode}} is never 
> switched on.
> * A {{struts.xml}} on the classpath is still loaded alongside the registry.
> * Example app {{apps/boot-hello}}, shaded into a runnable jar with 
> {{maven-shade-plugin}}; not deployed to Maven Central.
> * {{THREAT_MODEL.md}} gains a Boot section: the starter's container defaults 
> are in model.
> h2. Parked for later
> * Running an existing Struts WAR as a self-contained jar (migration path).
> * JSP views in the embedded container.
> * Gradle plugin.
> * Alternative containers (Jetty, Undertow).
> * Fluent definition of custom interceptor stacks.
> * Global results, global exception mappings, wildcard actions in the registry.
> * Optional bridge to Convention plugin annotations.
> * Dev-mode reload of templates and registry.
> * Project generator / quick-start archetype.
> * Health and info endpoints.
> * A dedicated Maven plugin or nested-jar launcher, needed before plugins can 
> be used in Boot apps (shading overwrites duplicate {{struts-plugin.xml}} 
> files).



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to