Beginner Spring MVC (based on Spring in Action)

Spring MVC(Model-View-Controller)

When you see this post, I guess you may be facing problems I have been explored before.

Like other bloggers, I will follow the book explain in detail the Spring MVC, to help her understand some of the more profound.

 

A tracking request Spring MVC

Whenever we encounter problems, we always turn to the browser.

As you find information in Baidu as search question, click on a link, and then view the contents inside.

1, when asked to leave the browser, always with the information you request, such as you may have just found in Spring MVC, which is information.

2, the first outbound request is front controller, in Spring MVC, which is DispatcherServlet.

     Its role is to send the request to the appropriate Spring MVC controller.

      Because there are various controller needs to process the request, the front end controller is to send the request to an appropriate controller.

3, the user sends a request, of course want to see the result. The controller will return some processed information to allow the user to see the request.

      The information the user wants to be seen is called model (Model).

      Of course, users definitely want to see more comfortable, so this information needs to be sent to the display view (View), usually a JSP.

4, the controller do not finished, it returns the actual value is a view name, model name and to pass the view data to headend controller (DispatcherServlet).

5, since we know the results displayed by the user want to see which view, the last stop request is the view of reality.

 

Second, set up Spring MVC

Since the principle has been clear, and then the next look at an example to better understand!

Our first step is to configure the above mentioned things the traditional way, usually using the web.xml to configure.

But the authors say the use JavaConfig better. Then we can compare these two methods.

1, the configuration DispatcherServlet

package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{

    @Override
    protected Class<?>[] getRootConfigClasses() 
    {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() 
    {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() 
    {
        return new String[] { "/" };
    }

}

As mentioned books, extend any class AbstractAnnotationConfigDispatcherServletInitializer class ---

And automatically configure DispatcherServlet Spring application context.

As you can see how to configure the following three functions rewritten.

GetServletMappings function will handle all the requests, the request is sent by the user are referred to SpringMVC to deal with.

GetRootConfigClasses function will be to configure the application context bean ContextLoaderListener created from RootConfig class.

GetServletConfigClasses DispatcherServlet function will be configured according to the application context bean WebConfig class.

Further configuration class @Configuration be annotated with, in order to allow the scanning assembly is configured to know which class.

 

2, then the contents of these two classes look

package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc @ComponentScan("spittr.web") public class WebConfig { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } }

Configuration class need to import org.springframework.context.annotation.Configuration;

@EnableWebMvc the need to enable SpringMVC,

Need to import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@ComponentScan comment assembly instructions to enable scanning, scan package for spittr.web,

Need to import org.springframework.context.annotation.ComponentScan;

The book said the deal with static resources may not be good, need to subclass and override configureDefaultServletHanding WebMvcConfigureAdapter method.

Currently I'm not quite sure where the bad, so here delete it.

Here you can see a view resolver, its role is to return the name of the view controller add a prefix and suffix, in order to know where to view files.

In front of the function @bean added a comment is to be added from the vessel to the spring, or else the view resolver does not take effect.

 

3, the next look RootConfig content

package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages = { "spittr" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig 
{

}

Here I talk about the role of @ComponentScan detail: the
configuration in the configuration class @ComponentScan package name indicate the scan classes in the package and its subpackages,

As long as the class code marked @ Controller, @ Service, @ Repository, @ Component spring will be loaded into the container.

Of course, the statement is displayed @bean, spring can be loaded directly into the vessel.

basePackages surface of the component package is scanned, it can be seen from the Packages, the value of the property may be an array.

excludeFilters specified to be excluded when the scanning assembly, includeFilters contains only when scanning the specified component,

Are useDefaultFilters open the default scanning rules.

例如:@ComponentScan(basePackages = "spittr",includeFilters = {},excludeFilters = {},useDefaultFilters = true)

excludeFilters and includeFilters are Filter Array, Filter, we need to specify the type, namely:

1, ANNOTATION annotation types

2, ASSIGNABLE_TYPE specified type

3, ASPECTJ ASPECTJ expression

4, REGEX regex

5, CUSTOM Custom

Examples of the book is to filter spittr package annotation types of components, with the value back, I guess that might be filtered inside the class notes, it is not loaded in the Spring container.

 

Third, the preparation of the basic controller

 1、HomeController

package spittr.web;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/home")
public class HomeController {

  @RequestMapping(method = GET)
  public String home(Model model) {
    return "home";
  }

}

The process controller "/ home" GET request, returns the view named home.

We look at Spittr home page index.jsp and home.jsp:

<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Spittr</title>
    <link rel="stylesheet" type="text/css" href="/resources/styles.css">
  </head>
  <body>
    <h1>Welcome to Spittr</h1>
    <a href="<c:url value="/home"/>">Home</a> |
    <a href="<c:url value="/spittles"/>">Spittles</a> |
    <a href="<c:url value="/spitter/register"/>">Register</a>
    
  </body>
</html>

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Welcome to you!
</body>
</html>

When we run index.jsp Click Home displays the Home page.

 

Fourth, the model data is transmitted to the view

In our Home Controller and did not return the data to the view, it only returns a view name can be said to be a super simple control of.

Now let's add to the view point data into it.

We first define a class Spittle:

package spittr;
import java.util.Date;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class Spittle 
{
    private final Long id;
    private final String message;
    private final Date time;
    private Double latitude;
    private Double longitude;

    public Spittle(String message, Date time)
    {
        this(message, time, null, null);
    }

    public Spittle(String message, Date time, Double latitude, Double longitude) 
    {
        this.id = null;
        this.message = message;
        this.time = time;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    public long getId() {
        return id;
    }

    public String getMessage() 
    {
        return message;
    }

    public Date getTime()
    {
        return time;
    }

    public Double getLongitude() 
    {
        return longitude;
    }

    public Double getLatitude() 
    {
        return latitude;
    }

    @Override
    public boolean equals(Object that) 
    {
        return EqualsBuilder.reflectionEquals(this, that, "id", "time");
    }

    @Override
    public int hashCode()
    {
        return HashCodeBuilder.reflectionHashCode(this, "id", "time");
    }
}

Then assume that we are in a data warehouse:

Define an interface SpittleRepository:

package spittr.data;
import java.util.List;
import org.springframework.stereotype.Component;
import spittr.Spittle;

@Component
public interface SpittleRepository 
{
    List<Spittle> findSpittles(long max, int count);

}

And then implement it:

package spittr.data;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Repository;
import spittr.Spittle;
@Repository
public class JdbcSpittleRepository implements SpittleRepository 
{

    private List<Spittle> createSpittleList(int count) 
    {
        List<Spittle> spittles = new ArrayList<Spittle>();
        for (int i = 0; i < count; i++) 
        {
            spittles.add(new Spittle("Spittle" + i, new Date()));
        }
        return spittles;
    }

    @Override
    public List<Spittle> findSpittles(long max, int count) 
    {
        // TODO Auto-generated method stub

        return createSpittleList(count);
    }

}

 

Now we realize the warehouse, the data can be generated Spittle. Then we write a Spittle controller: to put data into view.

package spittr.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import spittr.data.SpittleRepository;

@Controller
public class SpittleController 
{
    private SpittleRepository spittleRepository;

    @Autowired
    public SpittleController(SpittleRepository spittleRepository)
    { // 注入SpittleRepository
        this.setSpittleRepository(spittleRepository);
    }

    @RequestMapping(value="/spittles",method = RequestMethod.GET)
    public String spittles(Model model) 
    {
        // 将spittle添加到模型中
        model.addAttribute(spittleRepository.findSpittles(Long.MAX_VALUE, 20));
        return "spittles"; // 返回视图名
    }

    public SpittleRepository getSpittleRepository()
    {
        return spittleRepository;
    }

    public void setSpittleRepository(SpittleRepository spittleRepository) 
    {
        this.spittleRepository = spittleRepository;
    }

}

The controller @Autowired annotations looking @Repository annotation bean Spring container, and then injected into the bean.

That is to find the appropriate bean into parameter go in the Spring container.

In the processing method on the controller, i.e. with the parameters of the method @RequestMapping annotated model has a Model i.e.,

The controller may be passed to the view up by the parameter data.

Now we look spittles.jsp view:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Spitter</title>
    <link rel="stylesheet" type="text/css" href="<c:url value="../resources/style.css" />" >
  </head>
    <div class="listTitle">
      <h1>Recent Spittles</h1>
      <ul class="spittleList">
        <c:forEach items="${spittleList}" var="spittle" >
          <li id="spittle_<c:out value="spittle.id"/>">
            <div class="spittleMessage"><c:out value="${spittle.message}" /></div>
            <div>
              <span class="spittleTime"><c:out value="${spittle.time}" /></span>
            </div>
          </li>
        </c:forEach>
      </ul>

    </div>
  </body>
</html>

Finally, let us look at the results:

     


 

   


 

                                 

 

If it is used to configure the web.xml words:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>Java_Web</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
      <servlet-name>SpringDispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/SpringMVC.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
      <servlet-name>SpringDispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <context-param>   
      <param-name>contextConfigLocation</param-name>   
      <param-value>/WEB-INF/AppContext.xml</param-value>   
  </context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener> </web-app>

另外说明一下,如果是 SpringMVC.xml 文件放在src里的话:<param-value>classpath:SpringMVC.xml<param-value>。

同理:AppContext.xml也是一样。

 

接下来我们看下SpringMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

 <context:component-scan base-package="spittr"></context:component-scan>
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"></property>
    <property name="suffix" value=".jsp"></property>
 </bean>

</beans>

 该文件配置的是视图解析器,讲解了 javaConfig,这里就不多说了。

 

 

AppContext.xml 文件暂未配置啥,是个空文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">


</beans>

 

上面的包并没有单元测试和 mock 模拟测试包。

如果需要项目及相关包可以点此下载:Download

 

Guess you like

Origin www.cnblogs.com/M-Anonymous/p/11269197.html