http接口开发(json格式发送请求)
一.http接口
1.httpclient注意以json格式发送请求时entity为StringEntity
2.service端@ResponseBody:将请求处理后只返回响应体
3.service端以流的形式接受request请求
4.以下实例springmvc使用注解方式,mvc所需配置文件:
<mvc:annotation-driven >
<mvc:message-converters>
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=utf-8value>
<value>text/html;charset=UTF-8value>
<value>text/json;charset=UTF-8value>
<value>application/json;charset=utf-8value>
list>
property>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
bean>
property>
bean>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
5.接收json格式请求所需jackson Maven依赖:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.4.3version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.7.1version>
dependency>
<dependency>
<groupId>org.codehaus.jacksongroupId>
<artifactId>jackson-core-aslartifactId>
<version>1.9.13version>
dependency>
<dependency>
<groupId>org.codehaus.jacksongroupId>
<artifactId>jackson-mapper-aslartifactId>
<version>1.9.13version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.7.1version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.7.1-1version>
dependency>
httpclient完整代码:
public static final String ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM="MD5withRSA";
private String publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDazJE8JgkL4hXA5pJwuBu9skcCrA6cQBGws3G0rmIp/K51sqGVCradW8ait03/5/sUKoHDF2tu89dcuhTYBxgidMDmyBlAznU8WRt9FrgCtlhq4evcq+ZeUAPyXtvBMU18gNJq0EctJbszjTBkGvHuEuJes5lPs3nT+eHG1edwfQIDAQAB";
private String privatekey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANrMkTwmCQviFcDmknC4G72yRwKsDpxAEbCzcbSuYin8rnWyoZUKtp1bxqK3Tf/n+xQqgcMXa27z11y6FNgHGCJ0wObIGUDOdTxZG30WuAK2WGrh69yr5l5QA/Je28ExTXyA0mrQRy0luzONMGQa8e4S4l6zmU+zedP54cbV53B9AgMBAAECgYA/FCby3kxRXrbCzDZ/xLRKtjD+tjfoGBiBhtpLKtMmI7DwQbWP0GzhZOoZUxtroaejIrYSVpgkfqwiEYuc1D7Cd8N8ucXxG+UJE/lJoI9mlou5UAvEhJpjiWgKJDKkuRai3BfTBWDTCvDFrODPPeFaOGkIFgEFb+q2HoGOHjoOwQJBAPHlBHUz2M93Us2TKisTX+YrpZkyhEL6Z/U6EBcdVBhbnM9VFFT8g+qxQoFhsxg6xQe6I7vveRTR1cBDEqGzUkkCQQDnjsg1+RFdPRfJ4Z55KjdeP5Q2M3iLMGlPOSgcKKPXE7GI3A8rRY+STHXOgP+PWVESRGEG4LhyREwJHjGzRCyVAkEAq++kLoaOylC/W34KUBnyZVGK4IymtFD2ybjerP9cwf+EQ17vF8VxIsWiRwKh4UwMtoRZWAFMqD7KV2GVgbhLeQJAHEw1qWrjtVpG8vPwkuwW0hzA9xK5M4FaDUV14mMRCrKsaoZCEE6y6fUQHIllMdZ/ctUKanXB9KzmAeM/vaGiNQJAGk7xrqDAETApzZhwWmSxNzOJhVcOvo9URXwbwiuD/H5jsxCXMbIog5t0uiGhDN4Aqv5JeGODgGXbWcS598J8/A==";
@Test
public void Test() throws Exception {
HttpPost post = new HttpPost("http://192.168.1.163/KeXieUMC/getPersonByMemberId.htm");
//获取securityKey
PublicKey publicKey = getPublicKey(publickey);
PrivateKey privateKey = getPrivateKey(privatekey);
//拼装查询条件xxx=xxx&yyy=yyy&zzz=zzz
String param = "userId=11";
//签名
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initSign(privateKey);
sig.update(param.getBytes());
byte[] sign = sig.sign();
String signature = Base64.encodeBase64String(sign);
//加密
byte[] encrypt = encrypt(param, publicKey);
String encodeBase64String = Base64.encodeBase64String(encrypt);
//拼装json格式请求参数
JSONObject json = new JSONObject();
json.put("data", encodeBase64String);
json.put("signature",signature);
StringEntity entity = new StringEntity(json.toString(),"UTF-8");
//设置content编码及类型
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
post.setEntity(entity);
//模拟http post请求发送信息
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(post);
System.out.println(response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode() ==200){
HttpEntity entity_r = response.getEntity();
String personal = EntityUtils.toString(entity_r);
System.out.println(personal);
}
}
service端完整代码
@ResponseBody
@RequestMapping("/getPersonByMemberId.htm")
public JSONObject getPersonByMemberId(HttpServletRequest request) throws Exception{
JSONObject result = new JSONObject();
ServletInputStream inputStream = request.getInputStream();
StringBuffer buffer = new StringBuffer();
byte[] b = new byte[1024];
int len = 0;
while( (len = inputStream.read(b))!=-1){
buffer.append(new String(b, 0, len));
}
JSONObject json = JSONObject.fromObject(buffer.toString());
//获取密文
String data = json.get("data").toString();
//获取签名
String signature = json.get("signature").toString();
byte[] base64 = Base64.decodeBase64(data);
PrivateKey privateKey = Commons.getPrivateKey();
//获取明文
String value = Commons.decrypt(base64, privateKey);
//签名验证
boolean verify = Commons.verify(value.getBytes(), Base64.decodeBase64(signature));
if(!verify){
result.put("status", "failure");
result.put("message", "数字签名验证未通过,可能有被篡改的风险");
return result;
}
//明文处理
String[] arr = value.split("&");
HashMap map = new HashMap();
for(String entry : arr){
map.put(entry.split("=")[0], entry.split("=")[1]);
}
...
return result;
}
public static PublicKey getPublicKey(String key) throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
Base64.decodeBase64(key));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
public static PrivateKey getPrivateKey(String key)
throws NoSuchAlgorithmException, InvalidKeySpecException {
PKCS8EncodedKeySpec privatekeySpec = new PKCS8EncodedKeySpec(
Base64.decodeBase64(key));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(privatekeySpec);
}
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
commons
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class Commons {
public static final String ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM="MD5withRSA";
private static final String publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDazJE8JgkL4hXA5pJwuBu9skcCrA6cQBGws3G0rmIp/K51sqGVCradW8ait03/5/sUKoHDF2tu89dcuhTYBxgidMDmyBlAznU8WRt9FrgCtlhq4evcq+ZeUAPyXtvBMU18gNJq0EctJbszjTBkGvHuEuJes5lPs3nT+eHG1edwfQIDAQAB";
private static final String privatekey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANrMkTwmCQviFcDmknC4G72yRwKsDpxAEbCzcbSuYin8rnWyoZUKtp1bxqK3Tf/n+xQqgcMXa27z11y6FNgHGCJ0wObIGUDOdTxZG30WuAK2WGrh69yr5l5QA/Je28ExTXyA0mrQRy0luzONMGQa8e4S4l6zmU+zedP54cbV53B9AgMBAAECgYA/FCby3kxRXrbCzDZ/xLRKtjD+tjfoGBiBhtpLKtMmI7DwQbWP0GzhZOoZUxtroaejIrYSVpgkfqwiEYuc1D7Cd8N8ucXxG+UJE/lJoI9mlou5UAvEhJpjiWgKJDKkuRai3BfTBWDTCvDFrODPPeFaOGkIFgEFb+q2HoGOHjoOwQJBAPHlBHUz2M93Us2TKisTX+YrpZkyhEL6Z/U6EBcdVBhbnM9VFFT8g+qxQoFhsxg6xQe6I7vveRTR1cBDEqGzUkkCQQDnjsg1+RFdPRfJ4Z55KjdeP5Q2M3iLMGlPOSgcKKPXE7GI3A8rRY+STHXOgP+PWVESRGEG4LhyREwJHjGzRCyVAkEAq++kLoaOylC/W34KUBnyZVGK4IymtFD2ybjerP9cwf+EQ17vF8VxIsWiRwKh4UwMtoRZWAFMqD7KV2GVgbhLeQJAHEw1qWrjtVpG8vPwkuwW0hzA9xK5M4FaDUV14mMRCrKsaoZCEE6y6fUQHIllMdZ/ctUKanXB9KzmAeM/vaGiNQJAGk7xrqDAETApzZhwWmSxNzOJhVcOvo9URXwbwiuD/H5jsxCXMbIog5t0uiGhDN4Aqv5JeGODgGXbWcS598J8/A==";
//加密
public static String decrypt(byte[] text, PrivateKey key) {
byte[] dectyptedText = null;
try {
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(dectyptedText);
}
//解密
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
//base64ToPrivatekey
public static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException{
PKCS8EncodedKeySpec privatekeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privatekey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(privatekeySpec);
}
//base64ToPublickey
public static PublicKey getPublicKey() throws InvalidKeySpecException, NoSuchAlgorithmException{
X509EncodedKeySpec publickeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publickey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(publickeySpec);
}
public static boolean verify(byte[] data, byte[] sign) throws Exception {
PublicKey pubK = getPublicKey();
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(pubK);
sig.update(data);
return sig.verify(sign);
}
}
附 json处理日期格式 JSONConfig使用:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
public class DateJsonValueProcesseor implements JsonValueProcessor {
private SimpleDateFormat dateFormat;
private String datePattern = "yyyy-MM-dd";
public DateJsonValueProcesseor(String format) {
this.datePattern = format;
}
@Override
public Object processArrayValue(Object value, JsonConfig jsonConfig) {
return process(value);
}
@Override
public Object processObjectValue(String key, Object value,
JsonConfig jsonConfig) {
return process(value);
}
private Object process(Object value) {
try {
if (value instanceof Date) {
SimpleDateFormat sdf = new SimpleDateFormat(datePattern,Locale.UK);
return sdf.format((Date) value);
}
return value == null ? "" : value.toString();
} catch (Exception e) {
return "";
}
}
}
常见问题
1.base64加密:sun 包下的base64加密方法在未来版本可能会被废弃,不建议使用,如需强行使用可在maven中添加plugin-in…baidu,推荐使用org.apache.commons.codec.binary.Base64,功能强大;
2.PrivateKey、PublicKey可使用Stream的形式保存到本地(此时没有经过bse64转码)。RSA生成PrivateKey、PublicKey方法如下:
@Test
public void Test() throws NoSuchAlgorithmException, IOException {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(1024);
final KeyPair key = keyGen.generateKeyPair();
PrivateKey privateKey = key.getPrivate();
PublicKey publicKey = key.getPublic();
}
3.privatekey、publickey成对出现,使用时要注意。