基于服务器端保存用户的查询参数

基于服务器端保存用户的查询参数

最近公司项目有一个新的需求, 希望用户在PC查询的参数能够同步更新到APP端, 避免让用户在PC和APP端重复输入查询条件, 基于项目是前后端分离, APP和PC的请求参数都是一样的且都是POST请求, 因此考虑采用拦截器的方式拦截获取POST请求中的请求体, 同时前端请求后台时, 统一在Header中加入当前页面名称(pageName)的参数, 以用户Sessioin中的工号和pageName作为key, 将请求参数保存到Mongodb中, 基本的方案就是这样, 下面是具体实现

自定义线程池

/**
 * 线程池配置
 *
 * @author Eric on 2019/5/4.
 * @version 1.0
 */
@Configuration
public class ThreadPoolConfig {

	private static final int PROCESSOR_NUM = Runtime.getRuntime().availableProcessors();

	private static final int MIN_CORE_SIZE = PROCESSOR_NUM < 8 ? 16 : PROCESSOR_NUM * 2;

	private static final String DEFAULT_THREAD = "default";

	@Bean("default")
	public ThreadPoolTaskExecutor executorService() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setThreadNamePrefix(DEFAULT_THREAD);
		executor.setCorePoolSize(MIN_CORE_SIZE);
		executor.setMaxPoolSize(PROCESSOR_NUM * 16);
		executor.setQueueCapacity(PROCESSOR_NUM * 2);
		executor.setKeepAliveSeconds(30);
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}

}

自定义拦截器

HelloService封装了保存到Mongodb或者更新到Mongodb的操作
用户信息是从session中获取, 具体用户信息的实体类可以自定义

/**
 * 记录本次请求参数的拦截器
 *
 * @author wang.js on 2019/4/26.
 * @version 1.0
 */
@Component
public class RequestParamInterceptor implements HandlerInterceptor {

	@Resource
	private HelloService helloService;

	@Resource(name = "default")
	private ThreadPoolTaskExecutor executor;

	private static final Logger LOGGER = LoggerFactory.getLogger(RequestParamInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) {
		HttpSession session = httpServletRequest.getSession();
		if (session != null) {
			String pageName = httpServletRequest.getHeader("pageName");
			SystemUser user = (SystemUser) session.getAttribute("user");
			String body = new RequestWrapper(httpServletRequest).getBody();
			if (user != null && !StringUtils.isEmpty(pageName) && !StringUtils.isEmpty(body)) {
				executor.submit(() -> {
					helloService.saveOrUpdate(new MongoBean(pageName + user.getStaffCode(), body), "test");
					LOGGER.info("保存成功, key:{}, value:{}", pageName + user.getStaffCode(), body);
				});
			}
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {

	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {

	}

}

##HellService
HellService只是封装了Mongodb的保存和更新操作, 仅供参考

/**
 * @author wang.js
 * @date 2018/10/29
 * @copyright yougou.com
 */
@Service
public class HelloService {

    @Autowired
    private MongoBeanDao mongoBeanDao;

    /**
     * 保存
     * @param mongoBean
     */
    public void save(MongoBean mongoBean) {
        mongoBeanDao.insert(mongoBean, "test");
    }

    /**
     * 查找
     * @param id
     */
    public MongoBean find(String id, String collectionName) {
        Query query = new Query(Criteria.where("id").is(id));
        return mongoBeanDao.findByQuery(query, MongoBean.class, collectionName);
    }

    /**
     * 更新
     *
     * @param mongoBean
     * @param collectionName
     * @return
     */
    public boolean update(MongoBean mongoBean, String collectionName) {
        Update update = new Update().set("value", mongoBean.getValue());
        Query query = new Query(Criteria.where("id").is(mongoBean.getId()));
        mongoBeanDao.updateByQuery(update, query, MongoBean.class, collectionName);
        return true;
    }

    public void saveOrUpdate(MongoBean mongoBean, String collectionName) {
        MongoBean mongoBean1 = find(mongoBean.getId(), collectionName);
        if (mongoBean1 == null) {
            save(mongoBean);
        } else {
            update(mongoBean, collectionName);
        }

    }
}

##自定义HttpServletRequestWrapper
因为HttpServletRequest的输入流只能读取一次, 所以这里使用自定义HttpServletRequestWrapper将body中的信息保存起来, 方便后续多次使用
/**
* @author wang.js on 2019/4/26.
* @version 1.0
*/
public class RequestWrapper extends HttpServletRequestWrapper {

	private final String body;

	public RequestWrapper(HttpServletRequest request) {
		super(request);
		StringBuilder stringBuilder = new StringBuilder();
		BufferedReader bufferedReader = null;
		InputStream inputStream = null;
		try {
			inputStream = request.getInputStream();
			if (inputStream != null) {
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
				char[] charBuffer = new char[128];
				int bytesRead;
				while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
					stringBuilder.append(charBuffer, 0, bytesRead);
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		body = stringBuilder.toString();
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
		return new ServletInputStream() {
			@Override
			public boolean isFinished() {
				return false;
			}

			@Override
			public boolean isReady() {
				return false;
			}

			@Override
			public void setReadListener(ReadListener readListener) {
			}

			@Override
			public int read() throws IOException {
				return byteArrayInputStream.read();
			}
		};

	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(this.getInputStream()));
	}

	String getBody() {
		return this.body;
	}


}

##注册filter
/**
* 过滤器
*
* @author wang.js on 2019/4/26.
* @version 1.0
/
@WebFilter(urlPatterns = "/
",filterName = “channelFilter”)
public class ChannelFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		ServletRequest requestWrapper = null;
		if(servletRequest instanceof HttpServletRequest) {
			requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
		}
		if(requestWrapper == null) {
			filterChain.doFilter(servletRequest, servletResponse);
		} else {
			filterChain.doFilter(requestWrapper, servletResponse);
		}
	}

	@Override
	public void destroy() {

	}
}

##自定义webMvc的配置

/**
 * 自定义webMvc的配置
 *
 * @author Eric on 2018/8/19.
 * @version 1.0
 */
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {

	@Resource
	private RequestParamInterceptor requestParamInterceptor;

	/**
	 * 加入到Spring MVC的拦截器链中
	 *
	 * @param registry 拦截器注册
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(requestParamInterceptor);
	}

	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		super.configurePathMatch(configurer);
	}
}

以上操作就可以把在PC和APP端的请求参数保存到Mongodb中, 之后用户进入相应的页面时, 只需要根据当前页面的pageName来获取该用户上次的请求参数即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值