SpringMVC纯注解配置web.xml、json、静态资源、thymeleaf,递归json数组 - Go语言中文社区

SpringMVC纯注解配置web.xml、json、静态资源、thymeleaf,递归json数组


一些前面写过的(注解配置SpringMVC+Thymeleaf)这里将不重复多讲,该文章主要写如何注解配置静态资源、json converter,也有一些干货,由于搜不到一些递归json对象数组的jquery方法所以自己编写了一个递归输出json的方法。

Spring配置个人分为3个方面:

(1)容器配置(可通过web.xml或进行)

(2)根配置(数据层、常用Bean的配置,可通过xml文件或类进行配置)

(3)Servlet配置(配置页面所需bean,可通过xml文件或类进行配置)

1.容器配置:

无web.xml文件时Maven项目需在插件处添加以下设置(当xml不存在时不报错):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

通过类配置代替web.xml配置时配置类需实现WebApplicationInitializer接口或继承该接口的实现类,该实现类详解可看第一段链接的文章,以下是该文章的web.xml配置类

WebInitializer.java

package per.mvc.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import per.mvc.controller.WebConfig;


/**
 * Created by Wilson on 2017/5/21.
 */
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[0];
    }

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

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

}

2.根配置(配置数据源、数据接口等,发现之前写Thyleaf时没有写注解配置数据层,但由于该文章主题不是这个,所以该部分代码会以个人的以往例子配置贴到文章末尾给大家参考,但不会进行过多讲解)

3.Servlet配置

package per.mvc.controller;

import static com.alibaba.fastjson.serializer.SerializerFeature.*;

import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import com.google.common.collect.Lists;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;


import java.nio.charset.Charset;
import java.util.List;


/**
 * Created by Wilson on 2017/5/21.
 */
@EnableWebMvc
@Configuration
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public ITemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("UTF-8");
        return templateResolver;
    }

    @Bean
    public TemplateEngine templateEngine(ITemplateResolver templateResolver) {
        TemplateEngine templateEngine = new TemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);
        return templateEngine;
    }

    @Bean
    public ViewResolver viewResolver(TemplateEngine templateEngine) {
        ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
        thymeleafViewResolver.setTemplateEngine(templateEngine);
        thymeleafViewResolver.setContentType("text/html;charset=utf-8");
        return thymeleafViewResolver;
    }

    @Override	//配置默认信息转换器,需扩展则复写extendMessageConverters方法
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter4 fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter4();
        /*
            <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
            </property>
            上述xml配置相当于以下代码段,至于JSON的配置用的是阿里的fastjson,因Spring的json配置主要查找HttpMessageConverter接口的实现类及其子类,
            所以并非固定要用官方的
        */
        fastJsonHttpMessageConverter.setSupportedMediaTypes(Lists.newArrayList(
                MediaType.APPLICATION_JSON_UTF8, new MediaType(MediaType.TEXT_HTML, Charset.forName("UTF-8")), new MediaType(MediaType.TEXT_PLAIN, Charset.forName("UTF-8"))));
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(DisableCircularReferenceDetect, QuoteFieldNames,WriteNonStringKeyAsString,
                WriteNullListAsEmpty,WriteNullBooleanAsFalse,WriteMapNullValue,WriteNullStringAsEmpty);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastJsonHttpMessageConverter);
    }

   /* @Override     //由于已使用默认静态资源处理,所以该方法省去,只用于讲解
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //相当于 <mvc:resources mapping="/**" location="/img/" /> 也可设置多个路径
        registry.addResourceHandler("/**").addResourceLocations("/img/");
        registry.addResourceHandler("/**","/**").addResourceLocations("/js","/css/");
    }*/
}
以下是设置静态资源处理方法的源码,基于特定的URL路径样式为服务页面的静态资源添加资源处理器。该方法的参数位URL路径pattern,即静态资源的投影路径(对应xml的mapping),该方法返回对象用于设置资源文件的相对路径(调用该对象的addResourceLocation),相当于xml配置中的location

/**
 * Add a resource handler for serving static resources based on the specified URL path
 * patterns. The handler will be invoked for every incoming request that matches to
 * one of the specified path patterns.
 * <p>Patterns like {@code "/static/**"} or {@code "/css/{filename:\w+\.css}"}
 * are allowed. See {@link org.springframework.util.AntPathMatcher} for more details on the
 * syntax.
 * @return A {@link ResourceHandlerRegistration} to use to further configure the
 * registered resource handler
 */
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {
   ResourceHandlerRegistration registration =
         new ResourceHandlerRegistration(this.applicationContext, pathPatterns);
   this.registrations.add(registration);
   return registration;
}
控制层:

package per.mvc.controller;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import per.mvc.pojo.UserInfo;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Wilson on 2017/5/21.
 */
@Controller
@RequestMapping("/")
public class BaseController {
    @RequestMapping("/")
    public String home(){
        return "index";
    }
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
    @RequestMapping(value = "/obj")
    @ResponseBody
    public String obj(){
        return JSON.toJSONString(new UserInfo("Wilson-何","blog.csdn.net/z28126308"));
    }

    @RequestMapping(value = "/map")
    @ResponseBody
    public Map getMap(){
        Map map = new HashMap();
        map.put("data",Lists.newArrayList(new UserInfo("nameA","addressA"),new UserInfo("nameB","addressB")));
        return map;
    }
}

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script th:src="@{/js/jquery-1.8.3.js}"></script>
    <script th:src="@{/js/index.js}"></script>
    <link th:href="@{/css/font.css}" rel="stylesheet" type="text/css"/>
</head>
<body>
我是一个有样式的页面<br>
<button>first click</button>
<button>last click</button>
<div contenteditable="true"></div>
</body>
</html>

这里有点小细节需注意,若在mvc配置类中没有进行默认静态处理器的使能th:src的路径将无法访问,静态资源个人都放在webapp目录下,调用了以下方法后通过thymeleaf模板即可访问webapp目录下的静态资源,也可通过addResourceHandlers方法配置而不需启用默认处理,但一般都推荐使用默认静态资源处理器处理

启用默认静态资源处理:

public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

自定义静态资源处理(效果同上)

@Override     //若已使用静态处理则可省略该方法,pathPatterns的“/”路径是webapp下的路径,而不是/webapp/WEB-INF
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("/");
}

index.js(递归函数用于拼接递归后台传过来的各种解析后的JSON数据,由于百度到很多都只能遍历单个对象于是编写了该方法进行递归拼接)

/**
 * Created by Wilson on 2017/5/22.
 */
$(function () {
    $("button:first").on("click", function () {
        $.ajax({
            url: "obj",
            type: "GET",
            success: function (result) {
                $("div").append("object json:<br>" + result + "<br>"
                    + "parse object json:<br>" + ergodic($.parseJSON(result)) + "<hr/>");
            }
        })
    })
    $("button:last").on("click", function () {
        $.ajax({
            url: "map",
            type: "GET",
            success: function (responseText) {
                $("div").append("parse map json:<br>" + ergodic(responseText) + "<hr/>");
            }
        })
    })
})

//递归拼接字符串
function ergodic(obj) {
    var content = "";
    $.each(obj, function (key, value) {
        //检测到值若为对象则继续递归进行拼接
        if ($.type(value) == "object") {
            content += key + ":" + "{" + ergodic(value) + "}<br>";
        }
        //检测到值若为数组则继续递归进行拼接
        else if ($.type(value) == "array") {
            content += key + ":" + "[<br>" + ergodic(value) + "]<br>";
        }
        //检测到值若既非数组又非对象则连接键值
        else {
            content += key + ":" + value + ",";
        }
    })
    content = content.replace(/,}/, "}");
    content = content.replace(/,$/, "");
    return content;
}

项目目录图:

分别点击2个按钮后的页面结果图:





由于之前都没有写过数据层的注解配置,所以下面会提供一个mybatis数据层配置类代替xml配置给大家提供参考,包括了使用时还需在容器配置类的getRootConfigClasses方法中添加该类,如

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

package pers.graduation.config;

import java.util.Properties;

import javax.sql.DataSource;

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.core.io.Resource;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
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.context.annotation.Scope;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Repository;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan(basePackages = "pers", excludeFilters = {
      @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {
   @Bean
   protected DataSource getDataSource() {
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setUrl(
            "jdbc:mysql://localhost/****?serverTimezone=GMT");
      dataSource.setUsername("root");
      dataSource.setPassword("****");
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      return dataSource;
      /*
       * JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
       * factory.setJndiName("jdbc/orcl"); return (DataSource)
       * factory.getObject();
       */
   }

   @Bean
   protected DataSourceTransactionManager getTransactionManager(DataSource dataSource) {
      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
      return transactionManager;
   }

   @Bean("sqlSessionFactory")
   @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
   protected SqlSessionFactoryBean getSqlSessionFactory(DataSource dataSource,PageInterceptor pageInterceptor) throws Exception {
      SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
      factory.setDataSource(dataSource);
      ClassPathResource resource = new ClassPathResource("mybatis-config.xml");
      factory.setConfigLocation(resource);
      factory.setPlugins(new Interceptor[]{pageInterceptor});
      return factory;
   }

   @Bean		
   @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
   public MapperScannerConfigurer getMapperScannerConfigurer() {
      MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
      mapperScannerConfigurer.setBasePackage("xxx.xxx.dao");
      mapperScannerConfigurer.setAnnotationClass(Repository.class);
      mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
      mapperScannerConfigurer.setProperties(new Properties(){{put("mappers", "xxx.xxx.dao.base.BaseMapper");}});
      return mapperScannerConfigurer;
   }

   @Bean		//配置mybatis分页插件
   public PageInterceptor getPageInterceptor(){
      PageInterceptor pageInterceptor = new PageInterceptor();
      Properties properties = new Properties();
      properties.put("helperDialect","mysql");
      properties.put("offsetAsPageNum","true");
      properties.put("reasonable","true");
//    properties.put("rowBoundsWithCount","true");
      properties.put("pageSizeZero","true");
      properties.put("params","pageNum=start;pageSize=limit;pageSizeZero=zero;count=countSql");
      properties.put("supportMethodsArguments","true");
      pageInterceptor.setProperties(properties);
      return pageInterceptor;
   }
}

该文章的实例可以到我的博客资源处下载


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/z28126308/article/details/72627744
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 23:30:32
  • 阅读 ( 592 )
  • 分类:前端

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢