准备开Spring Security 权限工作
三.创建好Spring Security相应的工具类
- Constants:全局变量工具类
- jasksonAnnotationlntrospectorEx:扩展JACKSON对FastJson注释JSONField的支持工具类
- MultiReadHttpServletRequest:多次读写BODY用HTTP REQUEST工具类
- MultiReadHttpServletResponse:多次读写Body用HTTP RESPONSE工具类
- PassWordUtils :加密工具类
- ResponseUtils :使用response输出jsonn
3.1 创建Constants.class
package com.util;
import java.util.HashMap;
import java.util.Map;
/**
* 全局变量
*/
public class Constants {
/**
* 接口url
*/
public static Map<String,String> URL_MAPPING_MAP = new HashMap<>();
/**
* 获取项目根目录
*/
public static String PROJECT_ROOT_DIRECTORY = System.getProperty("user.dir");
/**
* 密码加密相关
*/
public static String SALT = "huangan";
public static final int HASH_ITERATIONS = 1;
/**
* 请求头 - token
*/
public static final String REQUEST_HEADER = "X-Token";
/**
* 请求头类型:
* application/x-www-form-urlencoded : form表单格式
* application/json : json格式
*/
public static final String REQUEST_HEADERS_CONTENT_TYPE = "application/json";
/**
* 未登录者角色
*/
public static final String ROLE_LOGIN = "role_login";
}
3.2 创建JacksonAnnotationIntrospectorEx.class
package com.util;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import java.lang.annotation.Annotation;
/**
* 扩展JACKSON对FastJson注释JSONField的支持
*/
public class JacksonAnnotationIntrospectorEx extends JacksonAnnotationIntrospector {
@Override
public boolean isAnnotationBundle(Annotation ann) {
if (ann.annotationType() == JSONField.class) {
return true;
}
return super.isAnnotationBundle(ann);
}
@Override
public PropertyName findNameForSerialization(Annotated a) {
PropertyName nameForSerialization = super.findNameForSerialization(a);
if (nameForSerialization == null || nameForSerialization == PropertyName.USE_DEFAULT) {
JSONField jsonField = _findAnnotation(a, JSONField.class);
if (jsonField != null) {
return PropertyName.construct(jsonField.name());
}
}
return nameForSerialization;
}
@Override
public PropertyName findNameForDeserialization(Annotated a) {
PropertyName nameForDeserialization = super.findNameForDeserialization(a);
if (nameForDeserialization == null || nameForDeserialization == PropertyName.USE_DEFAULT) {
JSONField jsonField = _findAnnotation(a, JSONField.class);
if (jsonField != null) {
return PropertyName.construct(jsonField.name());
}
}
return nameForDeserialization;
}
}
3.3 创建MultiReadHttpServletRequest.class文件
package com.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* 多次读写BODY用HTTP REQUEST - 解决流只能读一次问题
*/
@Slf4j
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private final byte[] body;
public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
body = getBodyString(request).getBytes(Charset.forName("UTF-8"));
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
/**
* 获取请求Body
* @param request
* @return
*/
private String getBodyString(ServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
/**
* 将前端请求的表单数据转换成json字符串 - 前后端一体的情况下使用
* @param request:
* @return: java.lang.String
*/
public String getBodyJsonStrByForm(ServletRequest request){
Map<String, Object> bodyMap = new HashMap<>(16);
try {
// 参数定义
String paraName = null;
// 获取请求参数并转换
Enumeration<String> e = request.getParameterNames();
while (e.hasMoreElements()) {
paraName = e.nextElement();
bodyMap.put(paraName, request.getParameter(paraName));
}
} catch(Exception e) {
log.error("请求参数转换错误!",e);
}
// json对象转json字符串 转javabean
// SecurityUser user = JSONObject.parseObject(JSONObject.toJSONString(bodyMap), SecurityUser.class);
// json对象转json字符串
return JSONObject.toJSONString(bodyMap);
}
/**
* 将前端传递的json数据转换成json字符串 - 前后端分离的情况下使用
* @param request:
* @return: java.lang.String
*/
public String getBodyJsonStrByJson(ServletRequest request){
// StringBuilder requestStrBuilder = new StringBuilder();
// try {
// BufferedReader streamReader = new MultiReadHttpServletRequest(request).getReader();
// String inputStr;
// while ((inputStr = streamReader.readLine()) != null) {
// requestStrBuilder.append(inputStr);
// }
// // 将json字符串转化为jsonbean对象
User user = JSON.parseObject(requestStrBuilder.toString(), User.class);
// } catch (IOException e) {
// e.printStackTrace();
// }
// return requestStrBuilder.toString();
StringBuffer json = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while((line = reader.readLine()) != null) {
json.append(line);
}
}
catch(Exception e) {
log.error("请求参数转换错误!",e);
}
return json.toString();
}
}
3.4 创建MultiReadHttpServletResponse.class 文件类
package com.util;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
/**
* 多次读写BODY用HTTP RESPONSE - 解决流只能读一次问题
*/
public class MultiReadHttpServletResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private HttpServletResponse response;
public MultiReadHttpServletResponse(HttpServletResponse response) {
super(response);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
this.response = response;
}
public byte[] getBody() {
return byteArrayOutputStream.toByteArray();
}
@Override
public ServletOutputStream getOutputStream() {
return new ServletOutputStreamWrapper(this.byteArrayOutputStream, this.response);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new OutputStreamWriter(getOutputStream(), this.response.getCharacterEncoding()));
}
@Data
@AllArgsConstructor
private static class ServletOutputStreamWrapper extends ServletOutputStream {
private ByteArrayOutputStream outputStream;
private HttpServletResponse response;
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener listener) {
}
@Override
public void write(int b) throws IOException {
this.outputStream.write(b);
}
@Override
public void flush() throws IOException {
if (!this.response.isCommitted()) {
byte[] body = this.outputStream.toByteArray();
ServletOutputStream outputStream = this.response.getOutputStream();
outputStream.write(body);
outputStream.flush();
}
}
}
}
3.5 创建PasswordUtils.class文件
package com.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.codec.Hex;
import java.security.MessageDigest;
/**
* 加密工具
*/
@Slf4j
public class PasswordUtils {
/**
* 校验密码是否一致
*
* @param password: 前端传过来的密码
* @param hashedPassword:数据库中储存加密过后的密码
* @param salt:盐值
* @return
*/
public static boolean isValidPassword(String password, String hashedPassword, String salt) {
System.out.print("password:"+password);
System.out.print("salt:"+salt);
System.out.print("加密:"+encodePassword(password, salt));
return hashedPassword.equalsIgnoreCase(encodePassword(password, salt));
}
/**
* 通过SHA1对密码进行编码
*
* @param password:密码
* @param salt:盐值
* @return
*/
public static String encodePassword(String password, String salt) {
String encodedPassword;
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1