servlet,SSM,jQuery实现JSONP跨域访问,数据的下拉框联动,面试题【诗书画唱】

概括:
src属性可以不受跨域访问问题的影响,可以放心地访问
后面的增删改查几乎全是用跨越访问来实现
servlet中使用JSONP实现跨域访问,打印传过来的JSON字符串的账号名的代码例子
SSM框架中使用JSONP实现跨域访问实现Oracle数据库中的数据的下拉框联动
jQuery实现JSONP跨域访问
例 1
例 2
例 3
可能的面试题:
JSON和JSONP有什么关系?
JSON:JS对象表示法,一种数据传输的格式要求
XML:可扩展标记语言,一种数据传输的格式要求
前端必知代码:


要知道的:


servlet中使用JSONP实现跨域访问,打印传过来的JSON字符串的账号名的代码例子 START

package com.SSHC.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
@WebServlet("/ms")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request,
* HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request,
* HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
//获取需要调用的函数的名字
String methodName = request.getParameter("callback");
System.out.println("调用的回调函数名是:" + methodName);
String data = "{\"act\":\"admin\",\"pwd\":666}";
//JSONP处理数据的代码跟普通的ajax处理代码不同,它需要调用回调函数,
//通过回调函数来进行处理
response.getWriter().write(methodName + "(" + data + ");");
}
}


//调用HBULIDER页面中的localFn函数
localFn('Hello Kitty!');





<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/jquery-1.11.0.js" ></script>
<script>
$(function(){
$('#btn').click(function(){
$.ajax({
url: 'http://localhost:8080/JSONPservlet/ms?callback=?',
async: false,
type: 'POST',
//设置跨域访问
dataType: 'jsonp',
success: function(data){
alert(data.act);
}
});
});
})
</script>
</head>
<body>
<input id="btn" type="button" value="发送数据" />
</body>
</html>

servlet中使用JSONP实现跨域访问,打印传过来的JSON字符串的账号名的代码例子 END
SSM框架中使用JSONP实现跨域访问实现Oracle数据库中的数据的下拉框联动 START
select * from addr
--drop table addr
create table addr (
id number primary key,
pid number,
name varchar2(20)
);
insert into addr values('1', '0', '湖南');
insert into addr values('2', '0', '江西');
insert into addr values('3', '0', '湖北');
insert into addr values('4', '0', '广东');
insert into addr values('5', '0', '福建');
insert into addr values('6', '1', '长沙');
insert into addr values('7', '1', '湘潭');
insert into addr values('8', '1', '娄底');
insert into addr values('9', '1', '株洲');
insert into addr values('10', '2', '宜春');
insert into addr values('11', '2', '萍乡');
insert into addr values('12', '2', '南昌');
insert into addr values('13', '3', '武汉');
insert into addr values('14', '3', '黄冈');
insert into addr values('15', '3', '孝感');
insert into addr values('16', '5', '厦门');
insert into addr values('17', '5', '福州');


package com.SSHC.bean;
public class Addr {
private Integer id;
private Integer pid;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


package com.SSHC.controller;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.SSHC.service.IMyService;
@Controller
public class SelController {
@Resource
private IMyService myService;
//http://localhost:8080/JSONPssm/loadData?pid=0&callback=abc
@RequestMapping(value = "loadData",method = RequestMethod.GET)
public @ResponseBody String loadData(@RequestParam Integer pid
,@RequestParam String callback){
String jsonStr = myService.getJson(pid);
return callback + "(" + jsonStr + ")";
}
}


package com.SSHC.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.SSHC.bean.Addr;
@Repository
public interface AddrDao {
List<Addr>selectByPid(Integer pid);
}


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace不能乱写,必须写成IUserinfoDao接口的全路径 -->
<mapper namespace="com.SSHC.dao.AddrDao">
<resultMap type="Addr" id="rmAddr">
<id property="id" column="ID"/>
<result property="pid" column="PID"/>
<result property="name" column="NAME"/>
</resultMap>
<!-- List<Addr>selectByPid(Integer pid) -->
<select id="selectByPid" resultMap="rmAddr">
select * from ADDR t where pid = #{pid}
</select>
</mapper>


package com.SSHC.service;
public interface IMyService {
String getJson(Integer pid);
}


package com.SSHC.service;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.SSHC.bean.Addr;
import com.SSHC.dao.AddrDao;
@Service
@Transactional
public class MyService implements IMyService {
@Resource
private AddrDao addrDao;
@Override
public String getJson(Integer pid) {
// TODO Auto-generated method stub
List<Addr>list = addrDao.selectByPid(pid);
//拼JSON字符串
StringBuilder jsonStr = new StringBuilder("[{\"id\":null,\"name\":\"请选择\",\"pid\":null},");
String dot = "";
for(Addr a : list) {
jsonStr.append(dot);
jsonStr.append("{");
jsonStr.append("\"id\":" + a.getId() + ",\"pid\":"
+ a.getPid() + ",\"name\":\"" + a.getName() + "\"");
jsonStr.append("}");
dot = ",";
}
jsonStr.append("]");
return jsonStr.toString();
}
}


package com.SSHC.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
@WebServlet("/ms")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().write("Hello world");
}
}


oracle_drivername=oracle.jdbc.driver.OracleDriver
oracle_url=jdbc:oracle:thin:@localhost:1521:orcl
oracle_username=X
oracle_password=sshcPwd

log4j.rootLogger=DEBUG,Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d[%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.SSHC.bean"/>
</typeAliases>
</configuration>

<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- 配置扫描注解,不扫描带有@Controller注解的类 -->
<context:component-scan base-package="com.SSHC">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 引入db.properties文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db.properties"/>
</bean>
<!--数据库连接池配置-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${oracle_drivername}"/>
<property name="url" value="${oracle_url}"/>
<property name="username" value="${oracle_username}"/>
<property name="password" value="${oracle_password}"/>
</bean>
<!-- 创建sqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 指定mybatis框架主配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis.xml"/>
<!-- 自动扫描mapping.xml文件,**表示迭代查找 ,,也可在mybatis.xml中单独指定xml文件 -->
<property name="mapperLocations" value="classpath:com/SSHC/dao/*.xml"/>
</bean>
<!-- 自动扫描com/SSHC/dao下的所有dao接口,并实现这些接口,
可直接在程序中使用dao接口,不用再获取sqlsession对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- basePackage 属性是映射器接口文件的包路径。
你可以使用分号或逗号 作为分隔符设置多于一个的包路径-->
<property name="basePackage" value="com/SSHC/dao"/>
<!-- 因为会自动装配 SqlSessionFactory和SqlSessionTemplate
所以没有必要去指定SqlSessionFactory或 SqlSessionTemplate
因此可省略不配置;
但是,如果你使用了一个以上的 DataSource,那么自动装配可能会失效。
这种情况下,你可以使用sqlSessionFactoryBeanName或sqlSessionTemplateBeanName属性
来设置正确的 bean名称来使用 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 使用声明式事务 transaction-manager:引用上面定义的事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<!-- 扫描@Controller注解 -->
<context:component-scan base-package="com.SSHC.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 默认注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter类 -->
<mvc:annotation-driven>
<!-- json乱码解决-->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- jsp引用外部js,css等静态资源的解决方法(和上面的标签必须同时出现,否则无法访问url) -->
<mvc:default-servlet-handler />
<!-- 配置视图名称解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<!-- 将所有的jsp文件存放在/WEB-INF/my/目录下 -->
<property name="prefix" value="/WEB-INF/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
<!-- 优先级设定 -->
<property name="order" value="10"></property>
</bean>
</beans>

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>JSONPssm</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base hreff="<%=basePath%>">
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" srcc="js/jquery-1.11.0.js"></script>
<script type="text/javascript">
$(function(){
$('#btn').click(function(){
$.ajax({
url: 'ms',
type: 'POST',
success: function(data){
alert(data);
}
});
});
})
</script>
</head>
<body>
<input id="btn" type="button" value="发送数据" />
</body>
</html>
http://localhost:8080/JSONPssm/loadData?pid=0&callback=abc


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
font-size: 50px;
}
</style>
<script type="text/javascript" srcc="js/jquery-1.11.0.js" ></script>
<script>
$(function(){
//请求省份下拉框中的数据
$.ajax({
url: 'http://localhost:8080/JSONPssm/loadData?callback=?',
async: false,
type: 'POST',
data: {
pid: 0
},
//设置跨域访问
dataType: 'jsonp',
success: function(data){
for(var i = 0;i < data.length;i ++) {
var prov = data[i];
//将省份加到下拉框中
$('#prov')[0].add(new Option(prov.name,prov.id));
}
}
});
$('#prov').change(function(){
//清空城市下拉框中的数据
$('#city')[0].length = 0;
//获取选中省份下拉框中的id
var id = $('#prov').val();
$.ajax({
url: 'http://localhost:8080/JSONPssm/loadData?callback=?',
async: false,
type: 'POST',
data: {
pid: id
},
//设置跨域访问
dataType: 'jsonp',
success: function(data){
for(var i = 0;i < data.length;i ++) {
var city = data[i];
$('#city')[0].add(new Option(city.name,city.id));
}
}
});
});
})
</script>
</head>
<body>
<select id="prov"></select>
<select id="city"></select>
</body>
</html>




SSM框架中使用JSONP实现跨域访问实现Oracle数据库中的数据的下拉框联动 END


JSON:JS对象表示法,一种数据传输的格式要求
XML:可扩展标记语言,一种数据传输的格式要求
JSONP:解决跨域访问的一种方式
JSON和JSONP有什么关系?
同源访问:
页面路径:http://localhost:8888/J190802SSM/index.jsp
调用路径:http://localhost:8888/J190802SSM/ms
跨域访问:
页面路径:http://127.0.0.1:8020/J190802/index.html
调用路径:http://localhost:8888/J190802SSM/ms
什么跨域访问:
当页面路径和调用路径出现了不同的时候,就会出现跨域访问的访问:
1、协议不同就会出现跨域访问
2、ip地址不同就会出现跨域访问
3、端口号不同就会出现跨域访问
4、项目名称不同就会出现跨域访问
页面路径:http://127.0.0.1:8020/J190802/JSONP.html
调用路径:http://localhost:8888/JSONPdemo/js/remote.js
JSONP跨域访问的核心技术就是利用script标签的src属性。
通过跨域访问实现下拉框联动效果




例1

例1

例 2-1


例 2-1的另一种写法

例 2-3

例 3

例 3






