一、拦截器

  在 Web 开发中,为了实现登录权限验证,我们不可能在每个方法中都写代码去验证身份信息,常见的是在 SpringBoot 中添加一个拦截器在用户的的请求到达 controller 层的时候实现登录验证。自定义的拦截器需要继承 HandlerInterceptorAdapter 类。

HandlerInterceptorAdapter

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {

	/**
	 * 在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回 true,则继续调用下一个拦截器。
	 * 如果返回 false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改 response 为你想要的响应。
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}

	/**
	 * 在方法执行后调用。
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	/**
	 * 在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

	/**
	 * This implementation is empty.
	 */
	@Override
	public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
			Object handler) throws Exception {
	}

}

自定义拦截器

  创建自定义的拦截器。

public class MyHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器执行");
        // 编写拦截规则
        return true;
    }
    }
}

  将自定义拦截器注入到 mvc 中。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截所有请求
        registry.addInterceptor(myHandlerInterceptor()).addPathPatterns("/**")
                // 不拦截指定请求
            .excludePathPatterns("/success");
    }

    public MyHandlerInterceptor myHandlerInterceptor() {
        return new MyHandlerInterceptor();
    }

}

二、实现国际化

  Spring Boot 支持本地化消息,以便您的应用程序可以满足不同语言首选项的用户。默认情况下,SpringBoot 默认国际化文件为:classpath:message.properties,如果放在其它文件夹中,则需要在 application.yml 配置属性 spring.messages.basename

编写国际化配置文件

  配置文件。

spring:
  messages:
    basename: i18n.login

image.png

  login.properties

login.btn= 登录~
login.password= 密码~
login.remember= 记住我~
login.tip= 请登录~
login.username= 用户名~

  login_en_US.properties

login.btn=login
login.password=password
login.remember=remember
login.tip=PleaseLogin
login.username=UserName

  login_zn_CN.properties

login.btn= 登录
login.password= 密码
login.remember= 记住我
login.tip= 请登录
login.username= 用户名

ResourceBundleMessageSource

  使用 ResourceBundleMessageSource 管理国际化资源文件,SpringBoot 自动配置好了国际化资源文件的组件。

	@Bean
	@ConfigurationProperties(prefix = "spring.messages")
	public MessageSourceProperties messageSourceProperties() {
		return new MessageSourceProperties();
	}

public class MessageSourceProperties {

	/** 我们的配置文件可以直接放在类路径下叫做 messages.properties
	 * Comma-separated list of basenames (essentially a fully-qualified classpath
	 * location), each following the ResourceBundle convention with relaxed support for
	 * slash based locations. If it doesn't contain a package qualifier (such as
	 * "org.mypackage"), it will be resolved from the classpath root.
	 */
	private String basename = "messages";

  可以通过配置文件修改默认配置。

spring:
  messages:
    basename: i18n.login

自定义 LocaleResolver

  SpringBoot 中 WebMvcAutoConfiguration 类中 localeResolver 方法定义国际化配置。默认是从浏览器的 Accept-Language 头部获取:国际化 Locale(区域信息对象),LocaleResolver (获取区域信息对象)。

		@Bean
		@ConditionalOnMissingBean
		@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
		public LocaleResolver localeResolver() {
			if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
				return new FixedLocaleResolver(this.mvcProperties.getLocale());
			}
			AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
			localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
			return localeResolver;
		}

  自定义 LocaleResolver 创建 MyLocaleResolver

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String l = request.getParameter("locale");
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(l)) {
            String[] split = l.split("_");
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}

  注入到 IOC 容器中。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}

使用国际化

  编写 HTML。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>Yi-Xing</title>
</head>
<body>

<h1>success</h1>
<p > 我的第一个段落。</p>
<p th:text="#{login.tip}">Welcome to our grocery store!</p>
<p > 我的第二个段落。</p>
<p th:text="#{login.btn}">Welcome to our grocery store!</p>
[[#{login.password}]]

</body>
</html>

  在 HTML 添加两个按钮,用来切换语言。

<a th:href="@{/success(locale='zh_CH')}"> 中文 </a>
<a th:href="@{/success(locale='en_US')}">English</a>

三、RESTFul 风格

  RESTFul 风格是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

URL 的定义

  URL:/资源名/资源标识 HTTP 请求方式区分对资源 CRUD 操作

普通 CRUD(通过 URL 来区分操作)RESTFul CRUD
查询getEmp?id=xxxemp/{id} GET
添加addEmp?xx=xxxemp POST
修改uadateEmp?id=xxx&xx=xxxemp PUT
删除deleteEmp?id=xxxemp/{id} DELETE

  请求架构

请求 URL请求方式
查询所有员工empsGET
查询某个员工(来到修改页面)emp/1GET
来到添加页面empGET
添加员工empPOST
修改员工empPUT
删除员工emp/1DELETE

URL 参数的注入  

  URL 参数注入例如:

    @GetMapping(value = "/success/{id}")
    public String success(@PathVariable("id") Integer id, Model model) {

  SpringBoot 在进行日期类型注入时默认是按照"/",自定义日期转换规则:

spring:
  mvc:
    date-format: yyyy-MM-dd

form 表单发送 put 和 delete 请求

 默认情况下 form 表单只能发 get,post 请求,发送 put 和 delete 请求方法如下:

  1. SpringMVC 中配置 HiddenHttpMethodFilter(SpringBoot 自动配置好,新版的 SpringBoot 默认关闭)doFilterInternal 过滤器中获取 _method 值。
  2. 页面创建一个 post 表单。
  3. 创建一个 input 项,name="_method",值就是我们指定的请求方式。
<input type="hidden" name="_method" value="put"/>

  SpringMVC 开启过滤器。

	@Bean
	@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
	@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = true)
	public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
		return new OrderedHiddenHttpMethodFilter();
	}

  SpringBoot 开启过滤器。

spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true

Spring 请求方式的注解

  @RequestMapping 注解,value 属性填写请求路径,method 填写请求方式。

@RequestMapping(value = "/", method = RequestMethod.POST)

  4 种请求方式的注解。

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping

  AJAX 请求方式的注解。

@ResponseBody

标题:SpringBoot 中拦截器的配置、国际化的实现以及 RestFul 风格接口
作者:Yi-Xing
地址:http://47.94.239.232:10014/articles/2020/04/01/1585754518619.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!