Web management using Spring MVC

1. Concept

MVC

MVC is an architectural model that divides program development into three levels: Mode, View, and Controller. The layers are separated from each other and work together. The View layer focuses on the presentation of data, the Model layer focuses on the composition of supporting business data, and the Controller completes business logic processing and data transfer.

The following is a MVC design pattern. First, the user request reaches the front controller Front Controller, which forwards the request to the Controller that can handle the request. The controller performs business processing and generates business data and returns it to the front controller. The Front Controller forwards the received business data to the page template, View template, renders it as the final page and returns it to the Front controller. Finally, the Front controller returns the final page to the user. In this mode, the Front controller is responsible for distribution scheduling, the Controller is responsible for processing business data, and the View template is responsible for rendering the page. The core idea of ​​MVC is to separate the processing and presentation of business data.

Spring MVC execution flow

  1.  The user sends a request to the server, this request will first go to the front controller DispatcherServlet (also called the central controller).
  2. DispatcherServlet will call the HandlerMapping processor mapper after receiving the request to get the execution chain where the request is processed. The so-called execution chain refers to the use of some interceptor Interceptor wrapped around the real processor Handler, some pre-processing before the request reaches the Handler, and some operations are performed after the Handler returns the execution result before returning the result.
  3. DispatcherServlet calls the HandlerAdapter processor adapter, telling the processor adapter which controller should be executed
  4. HandlerAdapter processor adapter to execute Controller and get ModelAndView (data and view), and return to DispatcherServlet layer by layer
  5. DispatcherServlet hands ModelAndView to ViewReslover view parser to parse, and then returns to the real view.
  6. DispatcherServlet fills the model data into the view
  7. DispatcherServlet responds the result to the user

2. Use Spring MVC

File configuration

As shown in the left figure below, manage a customers table to complete the user information query display and increase functions. First create a web project through maven and manually add models, views, controllers and other classes. The project structure is shown below

 

First configure the dependencies used by the project in the pom.xml file, such as servlet, mysql-connector, spring-webmvc, etc.

Then introduce two configuration files in the web.xml file : Spring framework's context configuration file application-context.xml and Spring MVC's configuration file mvc-dispatcher-servlet.xml. When configuring DispatcherServlet, specify the location of the configuration file through <init-param> contextConfigLocation, otherwise SpringMVC automatically finds the /web-INF/$servlet-name$-servlet.xml file according to <servlet-name> by default

It should be noted here that the <url-pattern> matching path "/" can only match URLs similar to / customer / view, "/ *" can not only match / customer / view, but also /view.jsp, /view.html and other suffixed URLs.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  
  <display-name>Archetype Created Web Application</display-name>

<!--配置Spring的上下文context-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/config/application-context.xml</param-value>
  </context-param>

<!--配置DispatcherServlet-->
  <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/mvc-dispatcher-servlet.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

The following is the application-context.xml file , in which the annotation-based bean management is enabled and the classes under com.mvc are automatically scanned, and the @Controller annotated beans are excluded through exclude-filter, because the @Controller class is then handed over to the DispatcherServlet management

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 启动基于注解的Bean管理 -->
    <context:annotation-config></context:annotation-config>

    <!-- 扫描com.mvc下的Bean -->
    <context:component-scan base-package="com.mvc">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

The following is the mvc-dispatcher-servlet.xml file , in which the annotated bean management is activated and the @Controller class is searched, and HandlerMapping is started. DispatcherServlet not only manages the Controller, but also manages the View. Configure ViewResolver as a JSTL template page, and add a prefix and suffix to the page. For example, the Controller returns the string success. Adding the prefix and suffix becomes /WEB-INF/jsps/success.jsp, so that you can find the corresponding page.

<?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: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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 激活注解 -->
    <context:annotation-config></context:annotation-config>

    <!-- 让DispatchServlet只搜索@Controller注解的类 -->
    <context:component-scan base-package="com.mvc">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 让DispatchServlet启用基于注解的HandlerMapping -->
    <mvc:annotation-driven/>

    <!-- 映射静态资源目录 -->
    <mvc:resources mapping="/resources/**" location="/resources"/>

    <!-- 配置ViewResolver为JstlView,并为其添加前后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsps/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

Write Controller

The following implementation displays the user's name by visiting the page with the url / customer / view? CustomerId = 3. The default value attribute of @RequestMapping specifies the mapped url path for the CustomerController class and the viewCustomer () method. You can also specify the type of response url through the method = RequestMethod.POST attribute.

In the viewCustomer () method, first obtain the parameter customerId in the url through the @RequestParam annotation , and then complete the operation of querying the database based on the id by calling CustomerService and return a customer object. The controller then binds the object to the Model object. Spring MVC carries data information through the Model object , and the front-end page can directly obtain the customer from the Model object.

Finally, the page string "customer_view" is returned , and the Dispatcher Servlet will stitch the correct page position according to the string. Not only can the page string be directly written, but also the redirect function can be realized for "redirect / forward:" + page.

@Controller
@RequestMapping("/customer")
public class CustomerController {
    private CustomerService customerService;

    @Autowired
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }

    @RequestMapping("/view")
    public String viewCustomer(@RequestParam("customerId") int id, Model model) {
        Customer customer = customerService.queryById(id);
        model.addAttribute(customer);           //将customer对象绑定到model中
        return "customer_view";
    }
}

The above is to obtain the parameter through @RequestParam and return the object through the Model object. You can also use the traditional HttpRequest object to obtain the parameters and bind the data

    @RequestMapping("/view")
    public String viewCustomer(HttpServletRequest request){
        int id=Integer.parseInt(request.getParameter("customerId"));    //获取参数
        Customer customer=customerService.queryName(id);
        request.setAttribute("customer",customer);                      //绑定返回对象
        return "customer_view";
    }

If the accessed URL is in the form of RESTful / customer / view / 3, you can get the parameters through @PathVariable. Map is used here to carry customer object information to the front end.

    @RequestMapping("/view/{customerId}")
    public String viewCustomer(@PathVariable("customerId")int id, Map<String,Object> model){
        Customer customer=customerService.queryName(id);
        model.put("customer",customer);
        return "customer_view";
    }

Finally, the information of the customer object is displayed by the EL expression on the customer_view.jsp page as follows

<h2>编号:${customer.id},名字:${customer.name}</h2>

Form data binding

SpringMVC will automatically complete the binding of the form data to the object. It should be noted that the name of the form attribute must be the same as the name of the object attribute. The following is a form for submitting a customer object, whose name is id and name correspond to the id and name attributes of the Customer object, respectively.

    <form action="<%=request.getContextPath()%>/customer/save" method="post">
        id:<input type="text" name="id">
        用户名:<input type="text" name="name">
        <input type="submit" value="提交">
    </form>

Receive the customer object in the form of parameters in the Controller and save the customer to the database through the customerService. Then redirect the page to the / customer / view page and pass in the customerId as the id of the customer object just saved.

    @RequestMapping(value = "/save",method = RequestMethod.POST)
    public String saveCustomer(Customer customer){
        System.out.println(customer.getId()+customer.getName());
        customerService.addCustomer(customer);
        return "redirect:view?customerId="+customer.getId();
    }

It is worth noting that the Chinese will be garbled when the form is submitted. This is required to set the encoding method to UTF-8 in the web.xml file

  <filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter </filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

File Upload

To use file upload in Spring MVC, first introduce maven dependency commons-fileupload in the pom.xml file, and then configure the bean CommonMultipartResolver in mvc-dispatcher-servlet.xml

    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>   <!--文件最大10M=10485760字节-->
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="resolveLazily" value="true"/>       <!--开启文件延迟解析-->
    </bean>

The file submission form is as follows: specify the enctype as multipart / form and the file name as imgFile

    <form method="post" action="<%=request.getContextPath()%>/customer/uploadImg" enctype="multipart/form-data">
        <input type="file" name="imgFile">
        <input type="submit" value="提交">
    </form>

Receive the picture in the Controller and save it, realize the file operation through the MultipartFile object, its isEmpty () is used to determine whether the file is empty, getInputStream () to obtain the file stream, getOriginalFilename () to obtain the file name. Copy the file to the newly created file object on the server through FileUtils' copyInputStreamToFile () method

    @RequestMapping(value = "/uploadImg",method = RequestMethod.POST)
    public String uploadImg(@RequestParam("imgFile") MultipartFile multipartFile) throws IOException {
        if (!multipartFile.isEmpty()){
            FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),
                    new File("D:\\Temp\\Pictures",multipartFile.getOriginalFilename()));
        }
        return "redirect:upload";
    }

Return JSON data

Sometimes we need the server not to return a page, but data in JSON format so that the front end can complete functions such as asynchronous loading. To use Json in Spring MVC, we must first introduce the dependency jackson-databind through maven. Then configure ContentNegotiatingViewResolver in mvc-dispatcher-servlet.xml to return data in JSON format by default.

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
            </list>
        </property>
    </bean>

After that, set the method in the Controller to directly return the Customer type object, and add @ResponseBody annotation

    @RequestMapping("/json_data")
    public @ResponseBody Customer getJsonData(@RequestParam("customerId") int id){
        return customerService.queryById(id);
    }

Accessing the url through a browser returns the data in JSON format as shown below

3. Interceptor

The interceptor in Spring MVC can be implemented by inheriting the HandlerInterceptor interface. This interface has three methods, of which preHandler () is the method for intercepting the request before it reaches the real Controller. It has a return value. If it is true, the request is released, and false means interception request. For example, in this method, whether the user is logged in is verified, and the verification is only released, otherwise, it is forwarded to the login page through request. postHandler () is the method executed by the interceptor after returning the result from the Controller. The parameters of this method include the ModelAndView object in addition to request, response, and handler. This object represents the data and view information returned by the Controller. The object modifies the returned data and view page. The afterCompletion () method is the method after the interceptor finishes execution, similar to the destructor, in which the operations of object destruction and connection closure are generally performed.

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求到达拦截器...");
        if (request.getSession().getAttribute("username") == null){         //验证是否已登录
            request.getRequestDispatcher("/WEB-INF/jsps/login.jsp").forward(request,response);
            return false;
        }else
            return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("返回结果到达拦截器...");
        modelAndView.addObject("msg","这是拦截器返回时添加的信息");        //修改返回的数据信息
        modelAndView.setViewName("/customer/add_customer");              //修改返回的视图页面
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器执行结束");
    }
}

After that, the interceptor must be registered in the mvc-dispatcher-servlet.xml file, where <mvc: mapping> specifies the request path for the interceptor to intercept.

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/customer_view"/>
            <bean class="com.mvc.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>


Published 124 original articles · Like 65 · Visit 130,000+

Guess you like

Origin blog.csdn.net/theVicTory/article/details/105567213