[java web]Idea+maven+spring4+hibernate5+struts2整合过程
摘要
最近也在网上找了些教程,试着使用maven进行包依赖关系的管理,也尝试着通过注解的方式来整合ssh框架。在这个过程中,踩了不少的坑。折腾很长时间,才算把架子折腾起来。这里把结果整理下,作为以后工作中的参考。
项目结构
关于maven如何使用,可自行搜索,默认你有一定的maven基础。maven建议中央仓库配置成阿里云的,可以下载速度快一些。地址
1、开始之前,需要通过maven进行ssh jar包引入。可以参考下面的pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion> <groupId>com.demo</groupId>
<artifactId>mavenapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <name>mavenapp Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url> <properties>
<!--源码编码-->
<project.build.sourceEncoding>UTF-</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- spring版本号 -->
<spring.version>4.3..RELEASE</spring.version>
<!-- hibernate版本号 -->
<hibernate.version>5.1..Final</hibernate.version>
<!-- struts2版本号 -->
<struts2.version>2.5.</struts2.version> </properties> <dependencies>
<!--JUnit4依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring 核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring web依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring整合ORM框架依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Struts2 核心依赖 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- Struts2和Spring整合依赖 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- Hibernate 核心依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- MySQL 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.</version>
</dependency>
<!-- C3P0 依赖 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.</version>
</dependency>
<!-- AspectJ依赖 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.</version>
</dependency>
<!-- SLF4J依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.</version>
</dependency> </dependencies>
<build>
<finalName>mavenapp</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
pom.xml
2、将resources设置为资源目录,并添加如上图所示的jdbc属性文件,struts2配置文件,日志属性文件,spring配置文件
内容分别如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 打开spring的annotation的支持 -->
<context:annotation-config/>
<!--引入jdbc属性配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/> <!--对me.demo下所有类文件进行扫描-->
<context:component-scan base-package="me.demo.*"/> <!--c3p0连接池配置-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--sessionFactory配置 可以省略hibernate.cfg.xml配置文件-->
<!--使用jpa注解形式的pojo对象,而去掉*.hbm.xml的Hibernate映射文件-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 设置spring去哪个包中查找相应的实体类 -->
<property name="packagesToScan">
<list>
<value>me.demo.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<!--是否自动创建表结构-->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--方言-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<!--hibernate中事务是需要在dao执行sql相关语句时来手动开启的,
然后底层实现代码时由getCurrentSession得到的session中可以得到transaction,所以可以正常运行.
这里,需要因为我们把sessionFactory的产生放在spring配置文件中,即让服务器启动时就创建这个对象,这样的话它就被存在一个上下文环境中,即在SpringSessionContext中保存
所以我们要把绑定当前线程session改成绑定这个spring上下文环境,即设置为由spring环境管理(因为事务aop也是在spring中),这时spring中的事务配置才会起作用(当然,以前是thread上下文环境的session,
而事务托管在spring上下文中,当然spring无法管理到thread上下文的session的事务)。-->
<prop key="hibernate.current_session_context_class">
org.springframework.orm.hibernate5.SpringSessionContext
</prop>
</props>
</property>
<!--自动扫描注解方式的hibernate类文件--> </bean> <!--事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 基于注解的事务,当注解中发现@Transactional时,使用id为“transactionManager”的事务管理器 -->
<!-- 如果没有设置transaction-manager的值,则spring以缺省默认的事务管理器来处理事务,
默认事务管理器为第一个加载的事务管理器 --> <tx:annotation-driven transaction-manager="transactionManager"/>
<!--配置事务的传播性-->
<!--<tx:advice id="transactionInterceptor" transaction-manager="transactionManager">-->
<!--<tx:attributes>-->
<!--<tx:method name="find*" read-only="true" />-->
<!--<tx:method name="get*" read-only="true" />-->
<!--<tx:method name="login*" read-only="true" />-->
<!--<tx:method name="add*" propagation="REQUIRED" />-->
<!--<tx:method name="update*" propagation="REQUIRED" />-->
<!--<tx:method name="delete*" propagation="REQUIRED" />-->
<!--<tx:method name="save*" propagation="REQUIRED" />-->
<!--<tx:method name="test*" propagation="REQUIRED" />-->
<!--<tx:method name="*Transaction" propagation="REQUIRED" />-->
<!--<tx:method name="*" propagation="REQUIRED" />-->
<!--</tx:attributes>-->
<!--</tx:advice>-->
<!--<!–配置哪些类的哪些方法参与事务 因为业务处理发生在service层,这里配置在service中的类–>-->
<!--<aop:config proxy-target-class="true">-->
<!--<aop:pointcut id="all-method" expression="execution(public * me.demo.service.*.*(..))"></aop:pointcut>-->
<!--<aop:advisor advice-ref="transactionInterceptor" pointcut-ref="all-method"/>-->
<!--</aop:config>-->
</beans>
applicationContext.xml
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sshdemo
jdbc.username=root
jdbc.password=abcd
jdbc.properties
log4j.rootCategory=INFO, console log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %t %c{}:%L - %m%n
log4j.properties
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<!--常量配置-->
<constant name="struts.objectFactory" value="spring"/>
<constant name="struts.i18n.encoding" value="utf-8"/>
<!--默认action配置-->
<package namespace="/" name="default" extends="struts-default">
<default-action-ref name="default"/>
<action name="default">
<result>/index.jsp</result>
</action>
</package>
<!--通过通配符的方式配置action-->
<package name="user" namespace="/" extends="struts-default">
<action name="user_*" method="{1}" class="userAction">
<result name="success">/index.jsp</result>
<allowed-methods>
register
</allowed-methods>
</action>
</package>
</struts>
struts.xml
3、三层结构,以及注解的使用
package me.demo.action; import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import me.demo.domain.User;
import me.demo.service.UserService;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller; @Controller("userAction")
@Scope("prototype") //默认是单例模式,需配置多例
public class UserAction extends ActionSupport implements ModelDriven<User> { private static final Logger log = LogManager.getLogger (UserAction.class);
private User user = new User ();
@Autowired
private UserService userService; @Override
public User getModel() {
return user;
} public String login() {
String login = userService.login (user);
return login;
} public String register() { System.out.println (user);
log.info (user);
String register = userService.register (user);
return register;
}
}
UserAction
package me.demo.dao.Impl; import me.demo.dao.UserDao;
import me.demo.domain.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository; import java.util.List; @Repository()
@Scope("prototype")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
@Autowired
public void setSessionFactoryOverride(SessionFactory sessionFactory) {
super.setSessionFactory (sessionFactory);
} @Override
public void save(User user) {
if (this.getHibernateTemplate () == null)
System.out.println ("getHibernateTemplate == null");
this.getHibernateTemplate ().save (user);
} @Override
public User find(String username, String password) {
List<User> users = (List<User>) this.getHibernateTemplate ().find ("from User where username=? and password=?", username, password);
if (users.size () > 0)
return users.get (0);
return null;
}
}
UserDaoImpl
package me.demo.dao; import me.demo.domain.User; /**
* 接口
*/
public interface UserDao { void save(User user); User find(String username, String password);
}
UserDao
package me.demo.domain; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*;
import java.io.Serializable; @Entity
@Table(name = "t_users")
public class User implements Serializable {
@Id
@GeneratedValue(generator = "autoGenerator")//根据数据库的主键生成策略
@GenericGenerator(name = "autoGenerator", strategy = "native")
private Integer id;
@Column
private String name;
@Column
private String password;
@Column
private Integer sex; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getSex() {
return sex;
} public void setSex(Integer sex) {
this.sex = sex;
} @Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex=" + sex +
'}';
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
}
User
package me.demo.service.Impl; import me.demo.dao.UserDao;
import me.demo.domain.User;
import me.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service()
@Scope("prototype")
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao; public String login(User user) {
User user1 = userDao.find (user.getName (), user.getPassword ());
if (user1 != null)
return "success";
return "not found";
} public String register(User user) {
userDao.save (user);
return "success";
}
}
UserServiceImpl
package me.demo.service; import me.demo.domain.User; public interface UserService {
String login(User user); String register(User user);
}
UserService
4、web
<%--
Created by IntelliJ IDEA.
User:
Date: 2018/6/8
Time: 17:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head> <body>
url:${pageContext.request.contextPath}
<a href="${pageContext.request.contextPath}/login.jsp">登录</a>
<a href="${pageContext.request.contextPath}/register.jsp">注册</a><br>
</body>
</html>
index.jsp
<%--
Created by IntelliJ IDEA.
User:
Date: 2018/6/8
Time: 17:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login" method="post">
姓名: <input name="name" type="text"> <br>
<input type="submit" value="登录"> </form>
</body>
</html>
login.jsp
<%--
Created by IntelliJ IDEA.
User:
Date: 2018/6/8
Time: 17:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user_register.action" method="post">
姓名: <input name="name" type="text"> <br>
密码:<input name="password" value="1234" type="password">
性别: <input name="sex" type="radio" value="1">男
<input name="sex" type="radio" value="0">女
<input type="submit" value="注册">
</form>
</body>
</html>
register.jsp
5、配置tomcat服务器,然后启动即可,会自动生成数据库表结构(前提自己手动创建好数据库)
6、测试
总结
1、虽然网络上这样的文章很多,但自己动手实现,发现还是有很多错误,发现最多的是,由jar的版本问题引起的,比如在配置问价中org.springframework.orm.hibernate5.LocalSessionFactoryBean这个类所在的包,在hibernate3,4,5中都有,如果你在配置文件中所写的,和HibernateDaoSupport所使用的包版本不一致,就会出错。
2、<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>,方言的配置,hibernate关于mysql的方言就有三个,这里采用MySQL5Dialect。
3、然后就是事务了,采用事务的注解,需要在配置文件中进行配置事务管理器。
annotation-driven:
这是xsd中 对事务管理器的描述。
Indicates that transaction configuration is defined by Java 5
annotations on bean classes, and that proxies are automatically
to be created for the relevant annotated beans. The default annotations supported are Spring's @Transactional
and EJB3's @TransactionAttribute (if available). Transaction semantics such as propagation settings, the isolation level,
the rollback rules, etc are all defined in the annotation metadata. See org.springframework.transaction.annotation.EnableTransactionManagement Javadoc
for information on code-based alternatives to this XML element.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="transaction-manager" type="xsd:string" default="transactionManager">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.transaction.PlatformTransactionManager"><![CDATA[
The bean name of the PlatformTransactionManager that is to be used
to drive transactions. This attribute is not required, and only needs to be specified
explicitly if the bean name of the desired PlatformTransactionManager
is not 'transactionManager'.
4、一定要有耐心。一个个解决问题,也是一种积累。
[java web]Idea+maven+spring4+hibernate5+struts2整合过程的更多相关文章
- [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- MyEclipse创建SSH项目(Java web由maven管理)
JavaEE后台开发,MyEclipse创建SSH项目,MyEclipse创建Java web 由maven管理的SSH项目. Demo工程源码github地址 1.创建SSH项目 1.创建web工程 ...
- JAVA web环境搭建(使用Tomcat8整合httpd)
说明:这里是Linux服务综合搭建文章的一部分,本文可以作为单独搭建Tomcat并整合httpd的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭建综合)的顺序来做的. 如果需要查 ...
- java web: eclipse & maven & jetty & struts2 & mysql = 简单登录页面
第一次接触java web开发,花费了一天半的时间,写了个简单的登录页面,以此文为记. 开发工具 Eclipse Luna Release (4.4.0) 已集成maven,maven目前的体会就是管 ...
- MyBatis数据持久化(十一)Mybatis3、Spring4、Struts2整合开发
上一节我们將Mybatis和Spring4进行整合,本节向大家介绍Mybatis在Web开发中的应用,并与主流的MVC框架Struts2进行整合. 我们首先需要获取Struts2框架,Struts2官 ...
- [原创]java WEB学习笔记65:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) ModelDriven拦截器 paramter 拦截器
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记55:Struts2学习之路---详解struts2 中 Action,如何访问web 资源,解耦方式(使用 ActionContext,实现 XxxAware 接口),耦合方式(通过ServletActionContext,通过实现 ServletRequestAware, ServletContextAware 等接口的方式)
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记54:Struts2学习之路---概述,环境的搭建
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- JavaScript的类型自动转换高级玩法JSFuck
0 前言 最开始是不小心在微信公众号(程序员大咖)看到一篇JS的高逼格代码,然后通过里面的链接跳转到了JSFuck的wiki,就像顺着迷宫找宝藏的感觉,感叹JS的自动类型转换的牛逼. 1 样例 (!( ...
- rem布局加载闪烁问题
说明:以下内容来自CSDN,如有侵权,请立刻联系博主(我),我将删除该内容. 原文链接 https://blog.csdn.net/u013778905/article/details/779387 ...
- Oracle12c 性能优化攻略:攻略1-2:创建具有最优性能的表空间
问题描述: 1:表空间是存储数据库对象(例如索引 .表)的逻辑容器. 2:在创建数据库对象不为其指定存储属性,则相应的表和索引会自动继承表空间的存储特性. 故:若需要好的索引.表的性 ...
- 配置本地无密码 SSH登录远程服务器
下面这幅图简单来说就是你本地有一把钥匙,服务器也有一把钥匙,当登录的时候本地的钥匙与服务器的进行对比,通过算法的判定,监测是否具有权限的用户 第一步,在本地配置这把钥匙生成私钥与公钥: 打开.ssh目 ...
- C++ code:判断字符串相等
如果两个字符串中0和1的个数分别相等,则称该对字符串为相等. 方法一: 由于string类对于读取文件中子串以及比较都很方便,所以,用string类的对象来逐对存放字串,然后将字串分别排序后对其进行比 ...
- python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)
昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...
- HDU 4763 求最大长度的串A,使得S满足APAQA
给一个串,让你找一个子串,形如EAEBE,就是一个串在开头结尾中间各出现一次,问这个E最长是多少 Sample Input5xyabcaaaaaaabaaaxoaaaaa Sample Output0 ...
- Ajax异步验证登陆或者注册
首先介绍一个不错的学习Ajax的中文网站:http://www.w3school.com.cn/ajax/index.asp AJAX = 异步 JavaScript 和 XML.详细介绍见上面的网址 ...
- [转] 详解webpack-dev-server的使用
webpack-dev-server是一个小型的Node.js Express服务器,它使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.j ...
- hihocoder 编程练习赛23
第一题:H国的身份证号码I 题意:一个N位的正整数(首位不能是0).每位数字都小于等于K,并且任意相邻两位数字的乘积也小于等于K.按从小到大的顺序输出所有合法的N位号码,每个号码占一行. 思路:dfs ...