#
以下内容是经过自己整理资料、官方文档所得:
web.xml 配置:
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <description>加载/WEB-INF/spring-mvc/目录下的所有XML作为Spring MVC的配置文件</description> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-mvc/*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
这样,所有的.htm的请求,都会被DispatcherServlet处理;
初始化 DispatcherServlet 时,该框架在 web 应用程序WEB-INF 目录中寻找一个名为[servlet-名称]-servlet.xml的文件,并在那里定义相关的Beans,重写在全局中定义的任何Beans,像上面的web.xml中的代码,对应的是dispatcher-servlet.xml;当然也可以使用<init-param>元素,手动指定配置文件的路径;
dispatcher-servlet.xml 配置:
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 使Spring支持自动检测组件,如注解的Controller --> <context:component-scan base-package="com.minx.crm.web.controller"/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /> </beans>
第一个Controller:
package com.minx.crm.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @RequestMapping("/index") public String index() { return "index"; } }
@Controller注解标识一个控制器,@RequestMapping注解标记一个访问的路径(/index.htm),return "index"标记返回视图(index.jsp);
注:如果@RequestMapping注解在类级别上,则表示一相对路径,在方法级别上,则标记访问的路径;
从@RequestMapping注解标记的访问路径中获取参数:
Spring MVC 支持RESTful风格的URL参数,如:
@Controller public class IndexController { @RequestMapping("/index/{username}") public String index(@PathVariable("username") String username) { System.out.print(username); return "index"; } }
在@RequestMapping中定义访问页面的URL模版,使用{}传入页面参数,使用@PathVariable 获取传入参数,即可通过地址:http://localhost:8080/crm/index/tanqimin.htm 访问;
根据不同的Web请求方法,映射到不同的处理方法:
使用登陆页面作示例,定义两个方法分辨对使用GET请求和使用POST请求访问login.htm时的响应。可以使用处理GET请求的方法显示视图,使用POST请求的方法处理业务逻辑;
@Controller public class LoginController { @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } @RequestMapping(value = "/login", method = RequestMethod.POST) public String login2(HttpServletRequest request) { String username = request.getParameter("username").trim(); System.out.println(username); return "login2"; } }
在视图页面,通过地址栏访问login.htm,是通过GET请求访问页面,因此,返回登陆表单视图login.jsp;当在登陆表单中使用POST请求提交数据时,则访问login2方法,处理登陆业务逻辑;
防止重复提交数据,可以使用重定向视图:
return "redirect:/login2"
可以传入方法的参数类型:
@RequestMapping(value = "login", method = RequestMethod.POST) public String testParam(HttpServletRequest request, HttpServletResponse response, HttpSession session) { String username = request.getParameter("username"); System.out.println(username); return null; }
可以传入HttpServletRequest、HttpServletResponse、HttpSession,值得注意的是,如果第一次访问页面,HttpSession没被创建,可能会出错;
其中,String username = request.getParameter("username");可以转换为传入的参数:
@RequestMapping(value = "login", method = RequestMethod.POST) public String testParam(HttpServletRequest request, HttpServletResponse response, HttpSession session,@RequestParam("username") String username) { String username = request.getParameter("username"); System.out.println(username); return null; }
使用@RequestParam 注解获取GET请求或POST请求提交的参数;
获取Cookie的值:使用@CookieValue :
获取PrintWriter:
可以直接在Controller的方法中传入PrintWriter对象,就可以在方法中使用:
@RequestMapping(value = "login", method = RequestMethod.POST) public String testParam(PrintWriter out, @RequestParam("username") String username) { out.println(username); return null; }
获取表单中提交的值,并封装到POJO中,传入Controller的方法里:
POJO如下(User.java):
public class User{ private long id; private String username; private String password; …此处省略getter,setter... }
通过表单提交,直接可以把表单值封装到User对象中:
@RequestMapping(value = "login", method = RequestMethod.POST) public String testParam(PrintWriter out, User user) { out.println(user.getUsername()); return null; }
可以把对象,put 入获取的Map对象中,传到对应的视图:
@RequestMapping(value = "login", method = RequestMethod.POST) public String testParam(User user, Map model) { model.put("user",user); return "view"; }
在返回的view.jsp中,就可以根据key来获取user的值(通过EL表达式,${user }即可);
Controller中方法的返回值:
void:多数用于使用PrintWriter输出响应数据;
String 类型:返回该String对应的View Name;
任意类型对象:
返回ModelAndView:
自定义视图(JstlView,ExcelView):
拦截器(Inteceptors):
public class MyInteceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mav) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception excptn) throws Exception { } }
拦截器需要实现HandleInterceptor接口,并实现其三个方法:
preHandle:拦截器的前端,执行控制器之前所要处理的方法,通常用于权限控制、日志,其中,Object o表示下一个拦截器;
postHandle:控制器的方法已经执行完毕,转换成视图之前的处理;
afterCompletion:视图已处理完后执行的方法,通常用于释放资源;
在MVC的配置文件中,配置拦截器与需要拦截的URL:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/index.htm" /> <bean class="com.minx.crm.web.interceptor.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors>
国际化:
在MVC配置文件中,配置国际化属性文件:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="message"> </bean>
那么,Spring就会在项目中搜索相关的国际化属性文件,如:message.properties、message_zh_CN.properties
在VIEW中,引入Spring标签:<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>,使用<spring:message code="key" />调用,即可;
如果一种语言,有多个语言文件,可以更改MVC配置文件为:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>message01</value> <value>message02</value> <value>message03</value> </list> </property> </bean>
sql server中如何连接表更新数据
假设a,b两表有外键关联,想要从b表中取出相应字段的值更新a表字段,可以有如下几种写法:
update a set a.name=b.name from a,b where a.id=b.id
update a inner join b on a.id=b.id set a.name=b.name where ...
update table1 set a.name = b.name from table1 a inner join table2 b on a.id =b
二:
表hotel中有id,hotel_city。
表hotel_room中有id,hotel_id,其中hotel_id与表hotel中的id对应。
表hotel_room_price中有room_id,price,price_year_month,其中room_id与hotel_room中的id对应。其余各项数据之间没有关联。
现在要求更新表hotel_room_price中的price字段,符合的条件是room_id对应的hotel_city是744,且price_year_month是'20114'。
SQL语句:
update hotel_room_price set price = 0 from hotel_room_price a,hotel_room b,hotel c where a.room_id = b.id and b.hotel_id = c.id and c.hotel_city = 744 and a.price_year_month = '20114'
重点看红色的部分。from后跟的是需要联立的三个表。用where a.room_id = b.id and b.hotel_id = c.id来将三个表当中需要对应的字段联立起来。and c.hotel_city = 744 and a.price_year_month = '20114'则是最后指定的两个条件。
运行无错误。
在调试zencart网店时,有时修改了某些文件,网店前台显示不完整了,或者出现了空白页面,可以通过以下方法打开错误提示:
版本 v1.3.9 的排错方法
错误记录在 /cache/ 目录下,前台的错误记录文件名为 "myDebug-xxxxxx.log" ,后台的错误记录文件名为 "myDebug-adm-xxxxxxx.log"
如果需要在浏览器中显示出错误信息(注意,客户也会看到错误信息),执行下面的操作:
如果是前台错误,打开文件 \includes\extra_configures\enable_error_logging.php
如果是后台错误,打开文件 \admin\includes\extra_configures\enable_error_logging.php
查找 @ini_set('display_errors', 0);
修改为 @ini_set('display_errors', 1);
版本 v1.3.8 的排错方法
前台界面排错适用
打开文件 \includes\application_top.php ,找到
if (defined('STRICT_ERROR_REPORTING') && STRICT_ERROR_REPORTING == true) {
在前面增加一行
define('STRICT_ERROR_REPORTING', true);
保存后重新刷新网页,就会有错误提示了。
把上面的语句修改为
define('STRICT_ERROR_REPORTING', false);
就能关闭错误提示了。
后台界面排错适用
打开文件 \admin\includes\application_top.php,找到
error_reporting(E_ALL & ~E_NOTICE);
修改为
@ini_set('display_errors', '1');
error_reporting(E_ALL);
找到错误后,再修改回去关闭错误提示
前两天在本地搭建一个网站,准备做下数据,安装好以后,发现登陆后台很慢,等了好久出现后台空白,开启错误提示也没用,根本就没错误,当时想,难道我这个站搭建的有问题。所以我又访问了以前搭建的站点,出现同样的错误。
难道是我本地环境出现问题了?或许是吧,所以一气之下就把本地环境重新搭建了一下,发现还是不行;难道是集成环境版本太低了,我又从官网下载一个新的,最后发现还是不行,不是这个问题。无语了……
然后我就再网上找啊找,最后根据一个的提示,我找到了一个解决办法,原来是线路的问题。前段时间我一直用的电信线路,最近换成了联通线路,就遇到这 样的问题,可能是最近联通线路有点问题。MD。折腾老子一下午才找到原因,为了避免和我一样的“程序猿”浪费时间,所以我就写下来,希望对你们有用。
解决办法:
把admin(网站后台目录)\includes\local\skip_version_check.ini文件里面的version_check=no修改成version_check=off 就可以了。
因为安装zen-cart的时候,默认会选择那个版本更新选项,当进入后台的时候,一直更新不了,所以会出现那个问题了。
自从上一篇
zen-cart采集规则和数据库发布模块下载以后。很多人问我为什么他的不能采集,原来发现他们用的几乎都是免费版的,不能直接导入数据库中,可以做成CVS格式的,但是遗憾的是不能下载图片,所以这次我就做个简单的教程,大致说一下。
quill.com 测试网站我用的是这个
第一种方式不能直接下载图片,但是可以通过迅雷下载。
第二种方式可以直接下载图片,但是批量中的那个图片字段有点乱,可以批量替换。
这两种方式下载图片的区别在于如图对比
第一种方式图1
第二种方式图2
今天答应两位朋友的要求,说说如何采集细节图!首先说说我是如何学会采集的吧,当时接触火车头采集器的时候,发现这方面的资料很少(针对 zencart的),什么采集规则,数据库发布模块,第一次用这玩意,有太多不明白的地方。我每天就不断查资料,不断测试,还好我是计算机专业的,学过一 些编程知识,将近花了一个星期才学会采集,当你看到你这篇文章时,希望你们也好好不断测试,不断分析问题,只有这样,以后遇到跟复杂的问题,才能会解决, 或许有些问题,只有少量的人遇到,只能靠自己了。好像很多人认为这个简单,也没有这方面的教程,可是对于我们这样的菜鸟来说,入门是必要的。也有一些收费 的,给别人采集一个站,做个批量表收多少钱等等。互联网提倡的就是资源共享,授人之鱼不如授人之渔。其实我对火车头采集器更多的功能没有深入了解,我只是 把我工作中学会的东西分享出来,再某些人看来,可能没有什么意义。我不会给别人采集一个网站收多少钱,说实话我现在还没那个能力,也没有太多的时间。废话 不多说了,开始今天的教程。
前面我的就不再介绍了,首先我找了一个有细节图的网站,例如www.jerseyscool.com。我们只看第二步:采集内容规则。我们添加一个标签名,就叫商品细节图,我的规则如下图(其实与商品图像差不多了)
然后要注意左下角的标签循环匹配,选择“添加为新记录”。看我采集的效果,只是我的网速慢,还没下载完 ,看到那个第几条记录没,就说明我们规则写对了,可以进行采集了。
最后一步要注意,搞zencart应该都知道,细节图是不写入数据库的,是根据图片名称匹配的,第三步设置如下图,不再在写入数据了,放到一个文件夹就行了。
最后需要说明的,我们做这一步是纯粹为了得到细节图。所以我要首先按照上一次的教程,采集完数据,然后再采集细节图。采集细节图我们可以一下子采集完,具体怎么采集明天到公司再补充(家里的网络实在太慢了,没法搞了)。这一次我就不把采集规则发上来了,其实很简单。
最近有人问我采集完了才做成批量表,其实很简单了,你在你的网站上安装一个批量表不就行了,可以把采集的数据放到另一个网站上,这一步我就操作了,不明白的可以给我留言或者加我q,最好是留言,我会认真回答你们的!
你们的鼓励是我最大的动力,我也是菜鸟,我们一起共同进步,最近一直在学习magento,下一步可能要针对magento进行采集了,呵呵,欢迎朋友们批评和指正!
首先安装zen-cart,我用的是zen-cart1.9中文版的,安装步骤我就不写了,这个很简单了。安装以后根据你要采集的网站建立对应的目录就OK了。例如我要测试采集的网站www.yankeesjerseystore.com这 是我随便找的网站,我首先建立大分类Shop By Players 然后建立相应的小分类Alex Rodriguez Jersey(多页面,等会解释这个)和Folder Alfonso Soriano Jersey(单页面)。我只是测试采集就先建一个大分类两个小分类。如下图
大分类
小分类
然后开始写采集规则了,每个网站的采集规则是不一样的,针对每个网站写不同的规则,不过zen-cart网站的规则差不多了,写多了就会发现很简单。
第一步写采集网址规则,首先添加采集地址(我添加的是http://www.yankeesjerseystore.com/new-york- yankees-jersey-alex-rodriguez-jersey-c-6_16.html?page=(*)&sort=20a)如 下图
然后为了采集自己想要的页面,就必须过滤一些网址了,就要写一些限制性的标志了,必须包含,不得包含,页面内选定区域采集网址从xx到xx等请看下图我是如何写的,这个不是唯一性的,每个人写的可能不一样。
这一步算是完成了。
第二步写采集内容规则,我把每个标签名对应规则放出来,如下图
商品名称
商品型号
商品价格
商品特价
商品图像,注意哪个文件保存格式,我选择了[原文件名],根据自己的需要也可以改
商品描述,注意用哪个html标签排除,我用了去首尾空白符
OK,规则写完了,可以找个内容页测试一下,如下图
看,已经测试成功了,注意图片一定要显示完整。
第三步发布内容设置,有几种发布方式,我选择方式三,导入到自定义数据库,如下图
然后点击数据库发布全局配置,选择编辑你要编辑数据库发布配置,如下图
点击编辑以后,出现下图
然后编辑数据库发布模块,如下图
看到你刚才写的标签名没,注意这个地方的标签与刚才写的标签名要对应着,,不然就会失败的,看到最后那个“2”没,就是刚才我们建立栏目时的分 类ID,每采集一个栏目的时候变换不同的ID,上面我已经写了,不需要改动了,最后我会把发布模块分享给朋友们。修改完以后,要点击那个“修改配置”这样 才能保存着。
第四步文件保存及部分高级设置,如下图,基本上不用改变。
最后一步,点击更新,然后就可以点击开始采集了,采集效果如下图
OK,采集成功了,可以发布到数据库了,然后我到网站后台看一下,是不是已经导入到数据库了,呵呵!如下图,成功了
后台效果
前台效果
最后要说明一点,采集单网址也是一样,注意选择如下图
好了,教程写完了,挺累的,写了两个小时,不知道你们看明白没,反正我是很明白(呵呵),根据不同的网站灵活运用就OK了,稍后我把采集规则放出来,供朋友下载,有不明白的地方可以给我留言或者加我qq
zen-cart.rar(点击下载哦)
PreparedStatement 使用like
在使用PreparedStatement进行模糊查询的时候废了一番周折,以前一直都没有注意这个问题。一般情况下我们进行精确查询,sql语句类似:select * from table where name =?,然后调用 PreparedStatement的setString等方法给?指定值。那么模糊查询的时候应该怎么写呢?我首先尝试了:select * from customer where name like ‘%?%’。
此时程序报错,因为?被包含在了单引号中,PreparedStatement并不视它为一个参数。后来上网查了相关的一些资料,发现可以这样写select * from table where name like ?;但是在指定参数的时候把?指定为”%”+name+”%”,name是指定的查询条件。这样就OK了。
一般情况下,我总是潜意识的认定了?就是取代所指定的参数,但是实际上我们可以对指定的参数进行了一定的包装之后再传给?,比如这里我们在参数的前后都加了一个%,然后再传给?
String expr = "select * from table where url like ?";
pstmt = con.prepareStatement(expr);
String a="a";
pstmt.setString(1, "%"+a+"%");//自动添加单引号 (包装后的参数)
pstmt.execute();
System.out.println(pstmt.toString());//打印sql
//会默认生成sql: select * from table where url like '%http%'
PHP $_GET
$_GET 变量是一个数组,内容是由 HTTP GET 方法发送的变量名称和值。
PHP $_POST
$_POST 变量用于收集来自 method="post" 的表单中的值。
$_POST 变量
$_POST 变量是一个数组,内容是由 HTTP POST 方法发送的变量名称和值。
$_POST 变量用于收集来自 method="post" 的表单中的值。从带有 POST 方法的表单发送的信息,对任何人都是不可见的(会显示在浏览器的地址栏),并且对发送信息的量也没有限制。
例子
<form action="welcome.php" method="post"
> Enter your name: <input type="text" name="name" /> Enter your age: <input type="text" name="age" /> <input type="submit" /> </form>
当用户点击提交按钮,URL 不会含有任何表单数据,看上去类似这样:
http://www.w3school.com.cn/welcome.php
"welcome.php" 文件现在可以通过 $_POST 变量来获取表单数据了(请注意,表单域的名称会自动成为 $_POST 数组中的 ID 键):
Welcome <?php echo $_POST["name"]
; ?>.<br /> You are <?php echo $_POST["age"]
; ?> years old!
为什么使用 $_POST?
- 通过 HTTP POST 发送的变量不会显示在 URL 中。
- 变量没有长度限制。
不过,由于变量不显示在 URL 中,所有无法把页面加入书签。
$_REQUEST 变量
PHP 的 $_REQUEST 变量包含了 $_GET, $_POST 以及 $_COOKIE 的内容。
PHP 的 $_REQUEST 变量可用来取得通过 GET 和 POST 方法发送的表单数据的结果。
例子
Welcome <?php echo $_REQUEST["name"]; ?>.<br /> You are <?php echo $_REQUEST["age"]; ?> years old!
ATTENTION:慎用$_REQUEST
如果get的一个变令名称和post的一个变量名称相同,则POST的值会覆盖GET的变量值
以为REQYEST先获取了get的值,然后获取了post的值,post的值会覆盖get值
我们可以来看php.ini中的配置
; This directive describes the order in which PHP registers GET, POST, Cookie,
; Environment and Built-in variables (G, P, C, E & S respectively, often
; referred to as EGPCS or GPC). Registration is done from left to right, newer
; values override older values.
variables_order = "EGPCS"
这个EGPCS就是说明用$_REQUEST数组获取内容的优先级,其字母的含义分别代表为:E代表$_ENV,G代表$_GET,P代表$_POST,C代表$_COOKIE,S代表$_SESSION。后面出现的数据会覆盖前面写入的数据,其默认的数据写入方式就是EGPCS,所以POST包含的数据将覆盖GET中使用相同关键字的数据。
通过这个我们也可以看出PHP获取参数的步骤
环境变量=》GET=》POST=》COOKIE=>SESSION
PHP中有$_REQUEST与$_POST、$_GET用于接受表单数据。
一、$_REQUEST与$_POST、$_GET的区别和特点
$_REQUEST[]具用$_POST[] $_GET[]的功能,但是$_REQUEST[]比较慢。通过POST和GET方法提交的所有数据都可以通过$_REQUEST数组获得。
二、$_POST、$_GET的区别和特点
1. GET是从服务器上获取数据,POST是向服务器传送数据。
2. GET是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。POST是通过HTTP POST机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
3. 对于GET方式提交表单数据,服务器端用$_GET[‘name’]获取变量的值,对于POST方式提交表单数据,服务器端用$_POST[‘name’]获取提交的数据,当然,两者都可以通过$_REQUEST[‘name’]获得表单数据。对于REQUEST方式提交表单数据,服务器端用$_REQUEST[‘name’]获取变量的值,但这种方式很少用。
4. GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般被默认为不受限制。但理论上,一般认为不能超过100KB。
5. GET安全性非常低,POST安全性较高。
6. GET表单值可以通过_GET获取;但通过action的url设置的参数总是获取不到的,<form method="get" action="a.asp?b=b">跟<form method="get"action="a.asp">是一样的,也就是说,在这种情况下,GET方式会忽略action页面后边带的参数列表。POST表单值可以通过_POST获取;但通过action的url参数设置的参数则可以不能通过_POST获取到。action=test.php?id=1这种就是GET方式传值,可以用$_REQUEST和$_GET接受传值,但不能用POST方式获取到值,即使表单是POST方式提交。所在,在提交表单时,如果action中同时有参数,最好只能通过POST表单方式,对于表单内数据,直接通过POST获取,对于action中参数,童工GET获取。
在做数据查询时,建议用GET方式,而在做数据添加、修改或删除时,建议用POST方式。
request是先读取 get再读post 的, 同时存在, 即覆盖掉前面的变量。
经典实例:
<?php
echo "get\n";
print_r($_GET);
echo "post\n";
print_r($_POST);
echo "request\n";
print_r($_REQUEST);
?>
<form method=post action='?a=1&b=2'>
<input type=text name=a value='a'>
<input type=text name=b value='b'>
<input type=submit value=test>
</form>
输出结果:
get:
Array
(
[a] => 1
[b] => 2
)
post:
Array
(
[a] => a
[b] => b
)
request:
Array
(
[a] => a
[b] => b
)
其实,在php配置文件php.ini中有一个设置项:variables_order = "GPCS" ,GPCS分别是GET,POST,Cookie,Server的首字母缩写,variables_order = "GPCS"含义是php文件中变量的解析顺序是GET,POST,Cookie和Server。