当前位置: 首页 > news >正文

港口备案怎么在网站做湖南网站建设kaodezhu

港口备案怎么在网站做,湖南网站建设kaodezhu,泰安高端网站建设,有字体设计网站Day48 手写Spring-MVC之前后置处理器与异常处理 前后置处理器 概念#xff1a;从服务器获取的JSON数据可能是加密后的#xff0c;因此服务端获取的时候需要进行解密#xff08;前置处理器#xff09;。 而从服务器传出的JSON数据可能需要加密#xff0c;因此需要在处理返…Day48 手写Spring-MVC之前后置处理器与异常处理 前后置处理器 概念从服务器获取的JSON数据可能是加密后的因此服务端获取的时候需要进行解密前置处理器。 而从服务器传出的JSON数据可能需要加密因此需要在处理返回值的时候进行加密后置处理器。 思路 首先搭建前后置处理器的框架 和是否处理JSON格式的数据类似需要根据注解判断controller层中的方法是否需要对JSON格式的数据进行解密或者返回数据进行加密因此要添加两个注解BeforeAdviser和AfterAdviser Target(ElementType.PARAMETER) Retention(RetentionPolicy.RUNTIME) public interface BeforeAdviser { }Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface AfterAdviser { }controller层的方法需要添加相应的注解标识 /*** 使用postman发送请求* url:http://localhost:8080/user/test12.action* json:{username:zs,password:123123}* 传递JSON参数和返回JSON*/RequestMapping(/test12.action)ResponseBodyAfterAdviserpublic User test12(RequestBody BeforeAdviser User user){System.out.println(user对象 user);return user;同时需要在参数描述类中和方法描述类中添加是否有相应注解的属性 /*** 参数描述类 */ NoArgsConstructor AllArgsConstructor Data public class ParameterDefinition {private String name;//参数名private Class? clazz;//参数类型private int index;//参数下标private Type[] actualTypeArguments;//参数泛型的数组private boolean requestBodyHasOrNot;//参数上是否有RequestBody注解private boolean beforeAdviserHasOrNot;//参数上是否有BeforeAdviser注解}/*** 方法描述类 */ NoArgsConstructor AllArgsConstructor Data public class MethodDefinition {private String requestMappingPath;//子级URiprivate String name;//方法名private Method method;//方法对象private Class? returnClazz;//返回值类型private ListParameterDefinition parameterDefinitions;//参数描述类对象的集合private boolean responseBodyHasOrNot;//方法上是否有ResponseBody注解private boolean afterAdviserHasOrNot;//方法上是否有AfterAdviser注解 }添加后监听器中封装部分也要进行相应修改 //获取参数上是否有BeforeAdviser注解 boolean beforeAdviserHasOrNot false; BeforeAdviser beforeAdviser parameters[i].getAnnotation(BeforeAdviser.class); if(beforeAdviser!null){beforeAdviserHasOrNot true; }ParameterDefinition parameterDefinition new ParameterDefinition(parameterName, parameterType, index,actualTypeArguments,requestBodyHasOrNot,beforeAdviserHasOrNot);//封装参数描述类对象 parameterList.add(parameterDefinition);//获取方法上是否有AfterAdviser注解 boolean afterAdviserHasOrNot false; AfterAdviser afterAdviser method.getAnnotation(AfterAdviser.class); if(afterAdviser!null){afterAdviserHasOrNot true; } MethodDefinition methodDefinition new MethodDefinition(sonUri, methodName, method, returnType, parameterList,responseBodyHasOrNot,afterAdviserHasOrNot);//封装方法描述类对象至此监听器就能把信息记录下来调度的DispatcherServlet进行工作的时候就可以获取到相应的注解信息。 前置处理器的使用是在获取参数类型的时候会判断是否有BeforeAdviser注解如果有则代表需要进行解密操作 //解密 if(parameterDefinition.isBeforeAdviserHasOrNot()){//在这里进行具体的解密操作吗 }在处理返回值的时候会判断方法是否有AfterAdviser注解如果有则代表需要进行加密操作 //加密 if(methodDefinition.isAfterAdviserHasOrNot()){//在这里进行加密操作吗 }进行具体的解密和加密操作 前后置处理器的框架搭建好之后会发现一个问题如果在DispatcherServlet中进行具体的解密加密的话那么在用户使用该框架的时候就只能使用框架所规定的解密加密这显然不具有灵活性。不同的用户解密、加密逻辑不同所以这里的思路是在框架中只写抽象类在DispatcherServlet中利用多态创建抽象类的继承类对象调用继承类对象中的解密加密方法。而在web模块中用户可以自己重写一个解密加密抽象方法这样调用的就是用户自定义的逻辑方法了。 抽象方法 public abstract class HanderAdviserResolver {public abstract String beforeRequestBody(String reqData);public abstract String afterResponseBody(String respData);public String before(String reqData){return beforeRequestBody(reqData);}public String after(String respData){return afterResponseBody(respData);} }注意这里的抽象方法是交给用户重写的而自己的成员方法则直接调用抽象方法通过这种方式实现在DispatcherServlet中调用用户重写方法的逻辑。 用户自定义前后置处理器 public class BeforeAndAfterAdviser extends HanderAdviserResolver {Overridepublic String beforeRequestBody(String reqData) {System.out.println(解密reqData);return reqData;}Overridepublic String afterResponseBody(String respData) {System.out.println(加密respData);return respData;} }又一个问题来了框架中怎样拿到用户自定义的类对象呢思路和监听器拿到controller层类对象相似通过配置文件拿到注解类注解类通过一个注解注明用户自定义的前后置处理器路径。这样的注解叫做使能注解它的功能就是使得DispatcherServlet能够拿到用户自定义类。然后在DispatcherServlet中重写init方法在方法中获取配置文件信息进而拿到注解类通过注解类的注解信息拿到自定义前后置处理器类对象调用其重写的解密加密处理方法。 使能注解 Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) public interface EnableAdviser {String adviserPackage(); }注解类 EnableAdviser(adviserPackage com.qf.shop.web.adviser.BeforeAndAfterAdviser)DispatcherServlet中: private HanderAdviserResolver adviserResolver;public HanderAdviserResolver getAdviserResolver(String config){try {Class? clazz Class.forName(config);EnableAdviser enableAdviserAnnotation clazz.getAnnotation(EnableAdviser.class);String adviserPackage enableAdviserAnnotation.adviserPackage();if(adviserPackage!null){Class? adviserClass Class.forName(adviserPackage);adviserResolver (HanderAdviserResolver) adviserClass.newInstance();}return adviserResolver;} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {throw new RuntimeException(e);}}Overridepublic void init() throws ServletException {ServletContext servletContext this.getServletContext();String config servletContext.getInitParameter(config);adviserResolver getAdviserResolver(config);}//加密 if(methodDefinition.isAfterAdviserHasOrNot()){jsonString adviserResolver.after(jsonString); }//解密 if(parameterDefinition.isBeforeAdviserHasOrNot()){jsonStr adviserResolver.before(jsonStr); }异常 概念DispatcherServlet中对于全局的异常需要进行处理而具体如何处理也是由业务决定的换言之是用户进行定义而非框架中写死。但是框架中又需要调用处理异常的方法如何处理-和前后置处理器一样通过多态servlet调用的是用户继承框架中抽象类的类重写的方法。 抽象类 public abstract class HanderGlobalException {public abstract void handlerException(Exception err, HttpServletRequest request, HttpServletResponse response);public void hander(Exception err, HttpServletRequest request, HttpServletResponse response){handlerException(err,request,response);} }用户继承类 public class GlobalException extends HanderGlobalException {Overridepublic void handlerException(Exception err, HttpServletRequest request, HttpServletResponse response) {System.out.println(处理全局异常......);try {request.getRequestDispatcher(/err.jsp).forward(request,response);} catch (ServletException | IOException e) {throw new RuntimeException(e);}} }那么框架如何拿到用户自己写的处理异常类和方法呢思路和前后置处理器一样DispactherServlet在重写的init方法中通过配置文件拿到配置类配置类通过框架中写的使能注解将用户自定义的异常处理类路径告诉servlet。 使能注解 Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) public interface EnableException {String exceptionPackage(); }配置类 /*** 当前项目的配置类 */ Configuration(com.qf.shop.web.controller) EnableAdviser(adviserPackage com.qf.shop.web.adviser.BeforeAndAfterAdviser) EnableException(exceptionPackage com.qf.shop.web.globalException.GlobalException) public class AppConfig { }DispatcherServlet: private HanderGlobalException globalException;public HanderGlobalException getGlobalException(String config){try {Class? clazz Class.forName(config);EnableException enableExceptionAnnotation clazz.getAnnotation(EnableException.class);String exceptionPackage enableExceptionAnnotation.exceptionPackage();if(exceptionPackage!null){Class? exceptionClass Class.forName(exceptionPackage);globalException (HanderGlobalException) exceptionClass.newInstance();}return globalException;} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {throw new RuntimeException(e);} }Overridepublic void init() throws ServletException {ServletContext servletContext this.getServletContext();String config servletContext.getInitParameter(config);adviserResolver getAdviserResolver(config);globalException getGlobalException(config);} try{//调用Controller层里的某个方法Object returnVal method.invoke(t, args);if(returnVal!null){//处理返回值handlerReturnVal(methodDefinition,returnVal,request,response,model);} }catch (Exception e){globalException.hander(e,request,response);//处理全局异常 }数据库模块 功能该模块不是Spring-MVC中的一部分是用来和数据库交互的框架。 思路分包逐步实现JDBC。 base包根据获得的结果集实现封装功能的接口包含结果集处理器接口和行处理器接口 /** * 结果集处理器的接口 *实现类BeanHandler(获取单个对象)、BeanListHandler(获取对象集合) */ public interface ResultSetHandlerT {public T handler(ResultSet resultSet)throws SQLException,IllegalAccessException,InstantiationException, InvocationTargetException; }/** * 行处理器的接口 * param T */ public interface RowProcessorT {public T toArray(ResultSet resultSet) throws SQLException; }handler包实现接口 /** * 结果集处理接口的实现类 * 操作结果集并封装实体类 * param T */ public class BeanHandlerT implements ResultSetHandlerT {private Class beanClass;public BeanHandler(Class beanClass) {this.beanClass beanClass;}Overridepublic T handler(ResultSet resultSet) throws SQLException, IllegalAccessException, InstantiationException, InvocationTargetException {ResultSetMetaData metaData resultSet.getMetaData();int columnCount metaData.getColumnCount();if(resultSet.next()){T t (T) beanClass.newInstance();for (int i 0; i columnCount; i) {String columnName metaData.getColumnName(i 1);Object columnValue resultSet.getObject(columnName);BeanUtils.copyProperty(t,columnName,columnValue);}return t;}return null;} } /** * 结果集处理接口的实现类 * 处理结果集并封装为集合 * param T */ public class BeanListHandlerT implements ResultSetHandlerListT {private Class beanListClass;public BeanListHandler(Class beanListClass) {this.beanListClass beanListClass;}Overridepublic ListT handler(ResultSet resultSet) throws SQLException, IllegalAccessException, InstantiationException, InvocationTargetException {ListT list new ArrayList();ResultSetMetaData metaData resultSet.getMetaData();int columnCount metaData.getColumnCount();while(resultSet.next()){T t (T) beanListClass.newInstance();for (int i 0; i columnCount; i) {String columnName metaData.getColumnName(i 1);T columnValue (T) resultSet.getObject(columnName);BeanUtils.copyProperty(t,columnName,columnValue);list.add(t);}}return list;} } /** * 结果集处理接口的实现类 * 操作结果集并封装数组对象 * * param T */ public class ArrayHandlerT implements ResultSetHandlerT {//行处理器private RowProcessorT rowProcessor;public ArrayHandler(RowProcessorT rowProcessor) {this.rowProcessor rowProcessor;}Overridepublic T handler(ResultSet resultSet) throws SQLException, IllegalAccessException, InstantiationException, InvocationTargetException {return rowProcessor.toArray(resultSet);} } 其中行处理的逻辑是拿到结果集后交给自定义的行处理接口实现类方法处理这样做的目的是统一代码的格式见后续web项目中的使用。 processor包处理行 /** * 行处理器的实现类将结果集中的数据获取并封装成数组 * param T */ public class BaskRowProcessorT implements RowProcessorT[] {private Class arrayTClass;public BaskRowProcessor(Class arrayTClass) {this.arrayTClass arrayTClass;}Overridepublic T[] toArray(ResultSet resultSet) throws SQLException {//创建数据容器ListT list new ArrayList();//遍历结果集while(resultSet.next()){T t (T) resultSet.getObject(1);list.add(t);}if(list.size()0||resultSetnull){throw new RuntimeException(参数异常无法获取泛型数组);}else {//创建数组T[] ts (T[]) Array.newInstance(arrayTClass, list.size());//添加数据for (int i 0; i list.size(); i) {ts[i] list.get(i);}return ts;}} } 通过结果集返回封装好的对象、列表、数组的功能已实现接下类实现操作数据库返回结果集的功能 core包 public class QueryRunner {private DruidDataSource dataSource;private ThreadLocalConnection local new ThreadLocal();public QueryRunner(DruidDataSource dataSource) {this.dataSource dataSource;}//获取连接private Connection getConnection() throws SQLException {Connection connection local.get();if(connectionnull){connection dataSource.getConnection();local.set(connection);}return connection;}//配置参数private PreparedStatement getPreparedStatement(Connection connection,String sql,Object... args) throws SQLException {PreparedStatement statement connection.prepareStatement(sql);for (int i 0; i args.length; i) {statement.setObject(i1,args[i]);}return statement;}//更新操作public int update(String sql,Object... args) throws SQLException {Connection connection getConnection();PreparedStatement statement getPreparedStatement(connection, sql, args);int i statement.executeUpdate();return i;}//查询操作public T T query(ResultSetHandlerT handler,String sql,Object... args) throws SQLException, InvocationTargetException, IllegalAccessException, InstantiationException {Connection connection getConnection();PreparedStatement statement getPreparedStatement(connection, sql, args);ResultSet resultSet statement.executeQuery();T t handler.handler(resultSet);return t;}} 至此框架搭建完毕接下来以用户创建的web项目举例 数据库工具类 public class JDBCUtils {//德鲁伊连接池引用private static DruidDataSource dataSource;static{//创建德鲁伊连接池dataSource new DruidDataSource();//获取配置信息Properties properties new Properties();try {properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream(DBConfig.properties));String username properties.getProperty(username);String password properties.getProperty(password);String url properties.getProperty(url);String driverName properties.getProperty(driverName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setDriverClassName(driverName);} catch (IOException e) {throw new RuntimeException(e);}}public static QueryRunner getQueryRunner(){return new QueryRunner(dataSource);} } controller层中对数据库进行操作 //---操作数据库--------------------------------------------------------------------------------------- RequestMapping(/test13.action) public void test13() throws SQLException {//操作更新语句JDBCUtils.getQueryRunner().update(update user set password ? where username ?,123456,zs); } RequestMapping(/test14.action) public void test14() throws SQLException, InvocationTargetException, IllegalAccessException, InstantiationException {//查询对象User zs JDBCUtils.getQueryRunner().query(new BeanHandler(User.class), select * from user where username ?, zs);System.out.println(zs); } RequestMapping(/test15.action) public void test15() throws SQLException, InvocationTargetException, IllegalAccessException, InstantiationException {//查询对象列表ListUser users JDBCUtils.getQueryRunner().query(new BeanListHandler(User.class), select * from user);for (User user : users) {System.out.println(列表中的对象user);} } RequestMapping(/test16.action) public void test16() throws SQLException, InvocationTargetException, IllegalAccessException, InstantiationException {//查询所有的usernameString[] usernames JDBCUtils.getQueryRunner().query(new ArrayHandler(new BaskRowProcessor(String.class)),select username from user);System.out.println(usernames); }遇到的问题 1.无法找到数据库连接的配置文件DBCfig.properties 解决方案将配置文件放到src/main/resources文件夹中去这样 资源文件才会被复制到target/classes 目录下。
http://www.hkea.cn/news/14453213/

相关文章:

  • 毕业设计做网站哪种好网站访问量怎么增加
  • 网站建设不用虚拟主机建筑公司网站电工
  • 中国电力建设股份有限公司网站协会网站建设的作用
  • 公司网站建设工作总结lnmp wordpress lamp
  • 网站换新域名商城类网站如何做seo
  • 做电影网站的程序长春建站价格
  • 上海城建建设官方网站熊掌号接入wordpress
  • 做视频能赚钱的网站东莞做网站
  • 旅游网站内容创可贴设计网
  • 公司企业如何做网站110平方装修全包价格
  • 青州市网站建设上海网站设计优刻
  • 做网站需要备注号码佛山定制网页设计
  • 公司网站是怎么样的免费浏览器
  • 制作企业网站的报告为shopify做推广的网站
  • icp备案查询站长之家省级网站 开发建设 资质
  • 网站的付款链接怎么做潍坊手机网站建设公司
  • 蓝气球卡地亚手表官方网站如何做链接
  • 抖音头像的网站制作教程市场推广和销售的区别
  • 解决wordpress更改新域名后网站不能访问的问题联系我们网站模板
  • 计算机毕设网站代做沧州建设网站的公司
  • 微网站建设步骤wordpress数据库连接文件
  • 网站制作建设怎么收费做网站选大公司好还是小公司
  • 婚庆网站的设计意义黄石网站设计
  • 做图有什么网站外贸展示网站多少钱
  • 购物网站建设合同Wordpress 打开xml rpc
  • 96个html静态网站模板打包沧州网站制作多少钱
  • 网站制作专业的公司wordpress显示登录注册
  • 怎样在工商局网站上做变更中国设计师个人网站
  • pr模板免费下载网站深圳自助体检机地址
  • 网站建设分金手指专业十九淘宝网站网页图片怎么做