2015年7月30日 星期四

Spring MVC2 and Apache Struts2

Spring and Apache MVC2

Spring
1. In application web.xml, define a 'servlet name' with a spring class and the URL pattern.  In the below example, the 'servlet name' is 'home'.    This is VERY important as spring looks for a ${servlet name}-servlet.xml in the same directory to set up the transfers between controller, modeler, and viewer.

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
<web-app>
<display-name>Spring MVC</display-name>
<servlet>
<servlet-name>home</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>home</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2. in home-servlet.xml, it tells spring that the MVC is annotation driven and the package name to scan for those MVC components.
<!-- the following two lines tell Spring what to do with the Application code -->
<mvc:annotation-driven />
<context:component-scan base-package="com.urpattern.circleme.springmvc" />
<!-- tells Spring what's the Viewer's URL pattern such as .jsp suffix -->
<!-- <mvc:resources mapping="/resources/**" location="/resources/" /> -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix">
<value>/views/</value>
</property>
<property name="suffix" value=".jsp" />
</bean>
</beans>
 Note the 'property' names and values given to the Spring '
InternalResourceViewResolver'
3. Component Annotation Scanning by Spring
The annotation tag @Controller tells Spring this is the application controller class. 
The annotation tag, @RequestMapping(/allhomes), tells Spring which URL, here '/allhomes', will be directed to this method of the controller, e.g. showAllHomes(Map<String, Object> model).  When transferring execution to this method, Spring also passes in a 'model'.  So the Controller prepares/calculates data and sets the return values in this 'model', then transfer execution to the Viewer (e.g. "home_list").   The viewer, home_list.jsp, will render the view of this 'model'.

The @autowire tells Spring to inject the instance of the class 'HomeService' into setHomeService() method.

@Controller
public class HomeController {
 ...
private HomeService homeService;
public HomeService getHomeService() {
return homeService;
}
@Autowired
public void setHomeService(HomeService homeService) {
this.homeService = homeService;
}
@RequestMapping("/allhomes")
public String showAllHomes(Map<String, Object> model) {
model.put("homes", getHomeService().fetchAllHomes());
return "home_list";
}

Deprecated Servlet in Struts2
org.springframework.web.servlet.DispatcherServlet

Missing Struts 1 Filter
java.lang.RuntimeException: java.lang.RuntimeException: com.opensymphony.xwork2.inject.DependencyException: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=java.lang.String, name='actionPackages'] in public void org.apache.struts2.config.ClasspathPackageProvider.setActionPackages(java.lang.String).

at com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:132)





From Codebehind to Convention Plugin

Changes required

  • Replace org.apache.struts2.config.Namespace with org.apache.struts2.convention.annotation.Namespace
  • Replace org.apache.struts2.config.Results with org.apache.struts2.convention.annotation.Results
  • Replace org.apache.struts2.config.Result with org.apache.struts2.convention.annotation.Result
  • Update @Result uses to use result name instead of Class<Result>
  • Update @Result uses to use location instead of value attribute
  • Update web.xml and remove Codebehind params from filter
  • Update CamelCase action results and references to match Convention. For example:
    Previously in Codebehind:
    Given an action named AnExampleAction, a request to /anExample -> AnExampleAction.execute() -> > anExample-index.ftl
    Now in Convention:
    Given an action named AnExampleAction, a request to /an-example -> AnExampleAction.execute() -> an-example-index.ftl

    The pathname is relative to the application context path if it starts with "/" otherwise it is relative to the default results directory.  e.g. if the request is http://localhost:8080/FindMe/userinfo/getname and the result is directed to "fail.jsp", then the 'fail.jsp' should be at http://localhost:8080/FindMe/WEB-INF/pages/userinfo/fail.jsp. Here, the application context is 'http://localhost:8080/FindMe' and the results directory is http://localhost:8080/FindMe/WEB-INF/pages as defined in the struts.xml properties
        <constant name="struts.convention.result.path" value="/WEB-INF/pages"/>

    All action, namespace, interceptor, and XWork package can be changed by annotations.

From import org.apache.struts2.config.ParentPackage; to import org.apache.struts2.convention.annotation.ParentPackage;


沒有留言:

張貼留言