SpringBoot Web 入门

SpringBoot Web

要解决的问题:

  • 导入静态资源
  • 首页
  • 模板引擎 Thymeleaf
  • 装配扩展SpringMVC
  • CRUD
  • 拦截器
  • 国际化

SpringMVC的自动配置类为WebMvcAutoConfiguration ,对应的properties类为WebMvcProperties

//WebMvcProperties部分代码
//在application配置文件中设置SpringMVC配置的属性在spring.mvc下
@ConfigurationProperties(prefix = "spring.mvc"
)
public class WebMvcProperties {private org.springframework.validation.DefaultMessageCodesResolver.Format messageCodesResolverFormat;private Locale locale;private WebMvcProperties.LocaleResolver localeResolver;private final WebMvcProperties.Format format;private boolean dispatchTraceRequest;private boolean dispatchOptionsRequest;private boolean ignoreDefaultModelOnRedirect;private boolean publishRequestHandledEvents;private boolean throwExceptionIfNoHandlerFound;private boolean logRequestDetails;private boolean logResolvedException;private String staticPathPattern;private final WebMvcProperties.Async async;private final WebMvcProperties.Servlet servlet;private final WebMvcProperties.View view;private final WebMvcProperties.Contentnegotiation contentnegotiation;private final WebMvcProperties.Pathmatch pathmatch;
//... ...

下面这是WebMvcAutoConfiguration中的添加资源处理程序

public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");} else {Duration cachePeriod = this.resourceProperties.getCache().getPeriod();CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();//1、第一种获取静态资源的方式 webjars //静态资源查找的路径 意思访问服务器路径/webjars/** 就可以映射访问到 classpath:/META-INF/resources/webjars/ 的			静态资源if (!registry.hasMappingForPattern("/webjars/**")) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));}//第二种获取静态资源的方式String staticPathPattern = this.mvcProperties.getStaticPathPattern();if (!registry.hasMappingForPattern(staticPathPattern)) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));}}
}

静态资源

第一种获取静态资源的方式使用webjars统一管理静态资源

webjars的官网

webjars的优点:

  • 将静态资源版本化,更利于升级和维护。
  • 剥离静态资源,提高编译速度和打包效率。
  • 实现资源共享,有利于统一前端开发。

可以在webjars的官网中引入

例如:

<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.5.1</version>
</dependency>

访问http://localhost:8080/webjars/jquery/3.5.1/jquery.js即可访问到静态资源jquery.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqGiLX3U-1610440101544)(C:\Users\郑大人\AppData\Roaming\Typora\typora-user-images\image-20200618002432542.png)]

第二种获取静态资源的方式

WebMvcAutoConfiguration中的addResourceHandlers(ResourceHandlerRegistry registry)方法中

//第二种获取静态资源的方式String staticPathPattern = this.mvcProperties.getStaticPathPattern();// staticPathPattern = /**if (!registry.hasMappingForPattern(staticPathPattern)) {//映射到下边四个资源路径下//1、classpath:/META-INF/resources/, //2、classpath:/resources/, //3、classpath:/static/, //4、classpath:/public/this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));}

staticPathPattern的值默认为/**,

//WebMvcProperties的构造函数
public WebMvcProperties() {this.localeResolver = WebMvcProperties.LocaleResolver.ACCEPT_HEADER;this.format = new WebMvcProperties.Format();this.dispatchTraceRequest = false;this.dispatchOptionsRequest = true;this.ignoreDefaultModelOnRedirect = true;this.publishRequestHandledEvents = true;this.throwExceptionIfNoHandlerFound = false;this.logResolvedException = false;//设置静态资源访问路径this.staticPathPattern = "/**";this.async = new WebMvcProperties.Async();this.servlet = new WebMvcProperties.Servlet();this.view = new WebMvcProperties.View();this.contentnegotiation = new WebMvcProperties.Contentnegotiation();this.pathmatch = new WebMvcProperties.Pathmatch();}

代表着http://localhost:8080/**可以直接访问静态资源,但是访问的却是,以下四个目录下的内容:

这四个目录优先级由高到底依次为

  1. classpath:/META-INF/resources/
  2. classpath:/resources/
  3. classpath:/static/
  4. classpath:/public/

原因在下面代码中

public class ResourceProperties {private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};private String[] staticLocations;private boolean addMappings;private final ResourceProperties.Chain chain;private final ResourceProperties.Cache cache;public ResourceProperties() {//静态资源路径this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;this.addMappings = true;this.chain = new ResourceProperties.Chain();this.cache = new ResourceProperties.Cache();}... ...

实践

我们可以修改staticPathPattern来实现修改静态资源访问路径

spring:mvc:static-path-pattern: /abc/**

静态资源总结

在springboot中,我们可以使用以下方式处理静态资源

  1. webjars

  2. classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/

    默认映射的访问路径为localhost:8080/**

    路径优先级: resources > static > public

首页如何定制

WebMvcAutoConfiguration自动配置类中

@Bean //欢迎页的处理映射
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());return welcomePageHandlerMapping;}private Optional<Resource> getWelcomePage() {String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());//去静态资源路径(之前的四个目录)中查找 index.html return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();}private Resource getIndexHtml(String location) {//在静态资源路径下查找 index.htmlreturn this.resourceLoader.getResource(location + "index.html");}

所以spring会去classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/下查找index.html主页

所以我们只需要在静态资源路径下创建index.html即可在http://localhost:8080/访问到主页

Thymeleaf模板引擎

  1. Thymeleaf官网
<!-- thtmeleaf 依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

ThymeleafProperties的部分代码

package org.springframework.boot.autoconfigure.thymeleaf;@ConfigurationProperties(prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {private static final Charset DEFAULT_ENCODING;//前缀  类似springMVC中视图解析器的配置public static final String DEFAULT_PREFIX = "classpath:/templates/";//后缀public static final String DEFAULT_SUFFIX = ".html";private boolean checkTemplate = true;private boolean checkTemplateLocation = true;private String prefix = "classpath:/templates/";private String suffix = ".html";private String mode = "HTML";private Charset encoding;private boolean cache;private Integer templateResolverOrder;private String[] viewNames;private String[] excludedViewNames;private boolean enableSpringElCompiler;private boolean renderHiddenMarkersBeforeCheckboxes;private boolean enabled;private final ThymeleafProperties.Servlet servlet;private final ThymeleafProperties.Reactive reactive;public ThymeleafProperties() {this.encoding = DEFAULT_ENCODING;this.cache = true;this.renderHiddenMarkersBeforeCheckboxes = false;this.enabled = true;this.servlet = new ThymeleafProperties.Servlet();this.reactive = new ThymeleafProperties.Reactive();}
... ...

所有在classpath:/templates/路径下的html文件都可以Controller中访问!

Thymeleaf语法文档

Thymeleaf语法

所有的html元素都可以被thymeleaf替换接管, th:属性名 :

<div th:text="${msg}"></div>

遍历

<!--<h4  th:each="user:${users}" >[[ ${user} ]]</h4>-->
<h4 th:each="user:${users}" th:text="${user}"></h4>

SpringMvc配置原理

WebMvcAutoConfiguration自动配置类中有个内部类是WebMvcAutoConfigurationAdapter是springMvc自动配置适配器

WebMvcAutoConfigurationAdapter这个类实现了WebMvcConfigurerSpringMvc配置接口。SpringMvc的默认配置就是由WebMvcAutoConfigurationAdapter来完成的。

@Configuration(proxyBeanMethods = false)@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})@Order(0)public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);private final ResourceProperties resourceProperties;private final WebMvcProperties mvcProperties;private final ListableBeanFactory beanFactory;private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;private final ObjectProvider<DispatcherServletPath> dispatcherServletPath;final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath) {this.resourceProperties = resourceProperties;this.mvcProperties = mvcProperties;this.beanFactory = beanFactory;this.messageConvertersProvider = messageConvertersProvider;this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.dispatcherServletPath = dispatcherServletPath;}public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {this.messageConvertersProvider.ifAvailable((customConverters) -> {converters.addAll(customConverters.getConverters());});}public void configureAsyncSupport(AsyncSupportConfigurer configurer) {if (this.beanFactory.containsBean("applicationTaskExecutor")) {Object taskExecutor = this.beanFactory.getBean("applicationTaskExecutor");if (taskExecutor instanceof AsyncTaskExecutor) {configurer.setTaskExecutor((AsyncTaskExecutor)taskExecutor);}}Duration timeout = this.mvcProperties.getAsync().getRequestTimeout();if (timeout != null) {configurer.setDefaultTimeout(timeout.toMillis());}}

如果我们需要自己设置SpringMvc的配置我们只需要,编写一个配置类重写WebMvcConfigurer中的方法即可。

该类有个要求需要@Configuration表示一个配置类,并且实现WebMvcConfigurer接口。如下图所示,可以重写很多的配置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cfcg9a3T-1610440101546)(C:\Users\郑大人\AppData\Roaming\Typora\typora-user-images\image-20200618161929080.png)]

/*** 定义一个WebMvcConfigurer 的实现类,可以重写SpringMvc的配置* 在这个类中 定义的组件,然后将它交给springboot,springboot就会自动装配*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Beanpublic ViewResolver myViewResolver(){return new MyViewResolver();}//自定义视图解析器public static class MyViewResolver implements ViewResolver{@Overridepublic View resolveViewName(String s, Locale locale) throws Exception {return null;}}
}

扩展SpringMvc配置

自定义配置类不能添加@EnableWebMvc,如果添加了 @EnableWebMvc,则WebMvcAutoConfigurationspringMvc自动配置类将会失效!!原因是@EnableWebMvc中导入了DelegatingWebMvcConfiguration类,而这个类继承了WebMvcConfigurationSupport

而在WebMvcAutoConfiguration的注解中有个注解是@ConditionalOnMissingBean({WebMvcConfigurationSupport.class}),

表示不能存在WebMvcConfigurationSupport,而自定义配置类如果添加@EnableWebMvc,就会导致WebMvcConfigurationSupport产生。所以自定义配置类不能添加@EnableWebMvc注解。

部分源码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class}) //!!!
public @interface EnableWebMvc {
}
@Configuration(proxyBeanMethods = false
)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {//!!!!
@Configuration(proxyBeanMethods = false
)
@ConditionalOnWebApplication(type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})///!!!!!
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {

Lombok使用

Lombok可以帮助我们生成POJO的getter/setter/toString,异常处理,I/O流的关闭操作等等

<!--        lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

lombok使用博客

image-20200618223224587 image-20200618223252861

国际化

原理

通过Properties文件配置,配置完后通过Thymeleaf中的#{} 来取代原来的静态资源。例如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9nPGTRW3-1610440101547)(C:\Users\郑大人\AppData\Roaming\Typora\typora-user-images\image-20200619152435951.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dG8OY03n-1610440101549)(C:\Users\郑大人\AppData\Roaming\Typora\typora-user-images\image-20200619001550264.png)]

spring:# 关闭模板引擎的缓存thymeleaf:cache: falsemessages:encoding: UTF-8## 配置国际化绑定的文件 不绑定会乱码basename: i18n.login

语言环境解析器接口

package org.springframework.web.servlet;import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;public interface LocaleResolver {//解析语言环境Locale resolveLocale(HttpServletRequest var1);void setLocale(HttpServletRequest var1, @Nullable HttpServletResponse var2, @Nullable Locale var3);
}

在SpringMvc自动配置类中语言环境解析器代码如下

public class WebMvcAutoConfiguration {//**语言环境解析器**public LocaleResolver localeResolver() {if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {return new FixedLocaleResolver(this.mvcProperties.getLocale());} else { //  AcceptHeaderLocaleResolver 默认的**语言环境解析器**AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();localeResolver.setDefaultLocale(this.mvcProperties.getLocale());return localeResolver;}}
}

默认使用的语言环境解析器

package org.springframework.web.servlet.i18n;import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;public class AcceptHeaderLocaleResolver implements LocaleResolver {private final List<Locale> supportedLocales = new ArrayList(4);@Nullableprivate Locale defaultLocale;public AcceptHeaderLocaleResolver() {}public void setSupportedLocales(List<Locale> locales) {this.supportedLocales.clear();this.supportedLocales.addAll(locales);}public List<Locale> getSupportedLocales() {return this.supportedLocales;}public void setDefaultLocale(@Nullable Locale defaultLocale) {this.defaultLocale = defaultLocale;}@Nullablepublic Locale getDefaultLocale() {return this.defaultLocale;}//!!!public Locale resolveLocale(HttpServletRequest request) {Locale defaultLocale = this.getDefaultLocale();if (defaultLocale != null && request.getHeader("Accept-Language") == null) {return defaultLocale;} else {Locale requestLocale = request.getLocale();List<Locale> supportedLocales = this.getSupportedLocales();if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);if (supportedLocale != null) {return supportedLocale;} else {return defaultLocale != null ? defaultLocale : requestLocale;}} else {return requestLocale;}}}@Nullableprivate Locale findSupportedLocale(HttpServletRequest request, List<Locale> supportedLocales) {Enumeration<Locale> requestLocales = request.getLocales();Locale languageMatch = null;Locale locale;label38:do {while(requestLocales.hasMoreElements()) {locale = (Locale)requestLocales.nextElement();if (supportedLocales.contains(locale)) {continue label38;}if (languageMatch == null) {Iterator var6 = supportedLocales.iterator();while(var6.hasNext()) {Locale candidate = (Locale)var6.next();if (!StringUtils.hasLength(candidate.getCountry()) && candidate.getLanguage().equals(locale.getLanguage())) {languageMatch = candidate;break;}}}}return languageMatch;} while(languageMatch != null && !languageMatch.getLanguage().equals(locale.getLanguage()));return locale;}//!!!public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) {throw new UnsupportedOperationException("Cannot change HTTP accept header - use a different locale resolution strategy");}
}

自定义语言环境解析器

我们自定义语言环境解析器,然后在引入到WebMvc配置类中,来替代原有的语言环境解析器。

我们只需要实现LocaleResolver接口即可

/*** 自定义 语言环境解析器*/
public class MyLocaleResolver implements LocaleResolver {//解析请求@Overridepublic Locale resolveLocale(HttpServletRequest httpServletRequest) {//获取请求中的语言参数Locale locale = null;final String language = httpServletRequest.getParameter("Language"); //例如 zh_CN  en_USSystem.out.println("------->"+language);if(!StringUtils.isEmpty(language)){ // return target == null || target.length() == 0;final String[] s = language.split("_");// s[0]:国家 s[1]:地区locale = new Locale(s[0],s[1]);return locale;}locale = Locale.getDefault(); // 如果没有请求参数就是默认的return locale;}@Overridepublic void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {}
}

将自定义的语言环境解析器,加入SpringMvc自动配置类中

在自动配置类中需要将自定义的MyLocaleResolver类取代WebMvcAutoConfiguration中对应的方法

/*** 定义一个WebMvcConfigurer 的实现类,可以重写SpringMvc的配置* 在这个类中 定义的组件,然后将它交给springboot,springboot就会自动装配*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {//自定义国际化组件  重写了 WebMvcAutoConfiguration 类中的  localeResolver 方法 @Beanpublic LocaleResolver localeResolver(){return new MyLocaleResolver();}}

效果图展示

拦截器

配置拦截器需要实现HandlerInterceptor处理程序拦截器接口。

package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;public interface HandlerInterceptor {//预先处理default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}//后期处理default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}//完成后default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}

实现一个登录拦截器

/*** 实现 HandlerInterceptor 处理程序拦截器 接口*/
public class LoginInterceptor implements HandlerInterceptor {//预先处理@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {final Object user = request.getSession().getAttribute("user");if(user == null){request.setAttribute("msg","您没有权限,请先登录");request.getRequestDispatcher("/").forward(request,response);//拦截return false;}else{//放行return  true;}}
}

将拦截器加入SpringMvc配置,并设置该拦截器拦截以及放行的路径

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {//我们写好的拦截器需要在这边添加。//添加拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {// addPathPatterns 拦截的路径// excludePathPatterns 排除拦截的路径registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html", "/", "/index", "/static/**","/login");}
}

addInterceptors方法是实现WebMvcConfigurer接口的方法,该方法是用来添加一个拦截器的。

下面是WebMvcConfigurerSpringMvc配置类接口中的方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package org.springframework.web.servlet.config.annotation;import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;public interface WebMvcConfigurer {default void configurePathMatch(PathMatchConfigurer configurer) {}default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}default void addFormatters(FormatterRegistry registry) {}//添加一个拦截器default void addInterceptors(InterceptorRegistry registry) {}default void addResourceHandlers(ResourceHandlerRegistry registry) {}default void addCorsMappings(CorsRegistry registry) {}default void addViewControllers(ViewControllerRegistry registry) {}default void configureViewResolvers(ViewResolverRegistry registry) {}default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}@Nullabledefault Validator getValidator() {return null;}@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}

下面是模拟登录,来使用登录拦截器:

@Controller
public class UserController {@RequestMapping("/login")public String Login(@RequestParam("username") String username ,@RequestParam("password") String password ,HttpServletRequest request ,HttpServletResponse response,Model model){if(!StringUtils.isEmpty(username) && "123456".equals(password)){request.getSession().setAttribute("user",username);return "dashboard";}else{model.addAttribute("msg","账号或密码错误");return "index";}}
}

效果展示

报错页面(404

只需要在templates目录下新建文件夹error,将404.html放置其中即可。(500也是如此)。

返回Json的处理

给实体类添加相关注解:

@JsonIgnore:指定字段不返回。

@JsonInclude(JsonInclude.Include.NON_NULL) :空字段不返回

@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”):设置响应时间格式

关于响应时间格式,可以统一在application文件中配置

spring:jackson:date-format: yyyy-MM-dd HH:mm:ss # 对输出时间格式化time-zone: GMT+8 # 北京时间相对伦敦有8小时的时差,使用GTM+8,这样才能正常显示时间

设置接收的日期格式

spring:mvc:format:date: yyyy-MM-dd  # 设置对输入参数格式化,这样后台就可以接收Date类型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

handler类型的定时器

2019独角兽企业重金招聘Python工程师标准>>> 一、采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的消息。这只是最主要的方法&#xff0c;当然Handler里还有其他的方法供实现&#xff0c;有兴趣的可以去查API&#xff0c;这里不过多解释。 1. 定义…

Vue路由基本操作

路由index.js import Vue from vue import VueRouter from vue-router import Home from ../views/Home.vue import Me from ../views/me.vue import About from "../views/About.vue" import Centor from "/views/Center.vue" import _404 from "..…

Windows 10 搭建Python3 安装使用 protobuf

Windows 10 搭建Python3 安装使用 protobuf Protobuf对比XML、Json等其他序列化的优势 protobuf 不管是处理时间上&#xff0c;还是空间占用上都优于现有的其他序列化方式。内存暂用是java 序列化的1/9&#xff0c;时间也是差了一个数量级&#xff0c;一次操作在1us左右。缺点…

Vue + SpringBoot跨域

Vue设置 1、在项目根目录创建文件vue.config.js module.exports {devServer: {proxy: {/api: {target: http://zlf.plus, //对应自己的接口changeOrigin: true,ws: true,pathRewrite: {^/api: }}}}}2、 在main.js中配置 import Vue from vue import App from ./App.vue imp…

Windows10 64位 安装 Postgresql 数据库

Windows10 64位 安装 Postgresql 数据库 1&#xff0c;下载Postgresql 10.7 版本&#xff0c;下载地址 https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2&#xff0c;打开安装包&#xff0c;傻瓜式默认安装&#xff0c;请谨记 “数据库密码” 和 “…

node.js入门小案例

nodejs 和 Java node.js是运行在服务端的JavaScript。node.js是一个基于chrome JavaScript 运行时建立的一个平台。底层架构 是JavaScript。 node.js是一个事件驱动I/O服务端JavaScript环境&#xff0c;chrome V8引擎执行JavaScript的速度非常快&#xff0c;性能非常好。 可以…

Windows10 64位安装DB2数据库

Windows10 64位安装DB2数据库 安装前准备 &#xff1a; 系统&#xff1a;Windows10 64位 DB2 v9.5下载地址&#xff08;迅雷&#xff09;&#xff1a;http://big3.ddooo.com/db2_93661.rar 选择安装包解压位置&#xff0c;并复制记住&#xff1a; 去到解压的安装目录&#xff…

npm包管理器安装模块

使用npm init 初始化目录(npm init -y) 可以省略中间过程 会在项目根目录生成一个文件 package.json&#xff08;类似于Maven 的pom文件&#xff09; {"name": "test","version": "1.0.1","description": "第一次创建…

Git报错: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

Git报错: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 在使用Git来克隆仓库报了错误&#xff0c;如下&#xff1a; fatal: unable to access ‘https://github.com/xiaobingchan/machine_learn/‘: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in co…

linux下的redis配置;

2019独角兽企业重金招聘Python工程师标准>>> linux环境下的php和redis的集成&#xff1a;http://blog.csdn.net/21aspnet/article/details/6960757 转载于:https://my.oschina.net/wangfree/blog/115987

Babel入门

Babel简介 Babel 是一个工具链&#xff0c;主要用于将 ECMAScript 2015 版本的代码转换为向后兼容的 JavaScript 语法&#xff0c;以便能够运行在当前和旧版本的浏览器或其他环境中。 中文文档 安装 npm install -g bable-cli 全局安装 babel --version 查看版本 Babel的…

Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能

Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能 Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能 Windows Server 2012 安装 SQL server 2008 出现了如下错误&#xff1a;解决方案1&#xff08;简单&#xff0c;界面操作&#xff09;&…

commonjs 和 es6模块化开发入门

commonjs模块化 首先写一个api&#xff0c;提供给外部调用 //commonjslet sum (a,b)> ab;// 暴露接口 module.exports {sum // sum:sum }导入调用 const m require(./Api.js)console.log(m.sum(10,20));es6模块化 首先写一个api&#xff0c;提供给外部调用 //es6 exp…

黑马程序员_7k面试题交通管理系统

------- android培训、java培训、期待与您交流&#xff01; ---------- //以下知识来在张孝祥老师的讲解总结 项目需求 模仿实现十字路口的交通灯系统逻辑&#xff0c;具体需求如下 1.异步随机生成按照各个线路行驶的车辆 例如&#xff1a; 由南而来去往北向的车辆......直行车…

eclipse搭建maven开发环境

eclipse搭建maven开发环境 eclipse搭建maven开发环境 maven作为一个项目构建工具&#xff0c;在开发的过程中很受欢迎&#xff0c;可以帮助管理项目中的bao依赖问题&#xff0c;另外它的很多功能都极大的减少了开发的难度&#xff0c;下面来介绍maven的安装及与eclipse的集成。…

mybatis-plus (3.4.2)使用

快速入门 官方文档快速入门案例 配置日志 # 配置日志mybatis-plus:configuration:# 配置 mybatis-plus执行的日志类型(可以看到执行过程) 下面是使用了控制台输出 sl4j log4j 等等都可以log-impl: org.apache.ibatis.logging.stdout.StdOutImpl效果 CRUD扩展 数据库中未指定…

SMTP 错误代码大全

为什么80%的码农都做不了架构师&#xff1f;>>> 421 Service not available, closing transmission channel (This may be a reply to any command if the service knows it must shut down) 450 Requested mail action not taken: mailbox unavailable (E.g., mai…

VituralBox从零搭建基于CentOS 7(64位)的Kubernetes+docker集群

VituralBox从零搭建基于CentOS 7&#xff08;64位&#xff09;的Kubernetesdocker集群 1. 下载CentOS 7官方minimal镜像2. 安装VituralBox&#xff08;Windows 10 64位&#xff09;3. 安装Git for windows&#xff08;Windows 10 64位&#xff09;4. 安装VituralBox虚拟机并创…

使用阿里云对象存储OSS收藏老婆新垣结衣日常照

目录阿里云OSS官方文档开通阿里云OSS服务入门使用java代码上传文件至OSS1、准备工作&#xff1a;创建阿里云OSS许可证(获取对Api的访问权限)选择继续使用 AccessKey创建AccessKey创建成功springBoot整合OSS依赖配置文件 application.yaml常量工具类OssControllerOssService效果…