Java基於ssm框架的restful應用開發
阿新 • • 發佈:2018-05-18
unicode ray -c mat after 內容 XP nco restful
Java基於ssm框架的restful應用開發
好幾年都沒寫過java的應用了,這裏記錄下使用java ssm框架、jwt如何進行rest應用開發,文中會涉及到全局異常攔截處理、jwt校驗、token攔截器等內容。
1、jwt工具類
直接貼代碼了,主要包括jwt的sign、verify、decode三個方法,具體實現如下:
package com.isoft.util;
import java.util.Date;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class JwtUtil {
private static final String SECRET = "xxxxx";
private static final String USERID = "userId";
private static final String ISSUER = "xxxx.com";
// 過期時間7天
private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000;
// jwt sign
public static String sign(Integer userId) {
try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithmHS = Algorithm.HMAC256(SECRET);
return JWT.create().withClaim(USERID, userId).withExpiresAt (date).withIssuer(ISSUER).sign(algorithmHS);
} catch (Exception e) {
return null;
}
}
// jwt verify
public static boolean verify(String token, Integer userId) {
try {
Algorithm algorithmHS = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithmHS).withClaim(USERID, userId).withIssuer(ISSUER).build();
verifier.verify(token);
return true;
} catch (Exception e) {
System.out.println(e);
return false;
}
}
// 返回token中的用戶名
public static Integer getUserId(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim(USERID).asInt();
} catch (Exception e) {
return null;
}
}
}
2、全局異常處理類
ssm中進行rest全局異常攔截處理主要用到RestControllerAdvice型註解類,直接貼代碼:
package com.isoft.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.isoft.po.Response;
@RestControllerAdvice
public class ExceptionAdvice {
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public Response handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
return new Response().failure("could not read json");
}
/**
* 405 - Method Not Allowed
*
* @param e
* @return
*/
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
return new Response().failure("request method not supported");
}
/**
* 500 - Internal Server Error
*
* @param e
* @return
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public Response handleException(Exception e) {
System.err.println(e);
return new Response().failure(e.getMessage());
}
}
這裏主要攔截了405、400、500的n行yi‘chang異常情況,可根據具體情況拓展。
3、自定義Response返回類
我們自定義的Response返回類格式如下:
{
"meta": {
"success": true,
"message": "ok"
},
data: Array or Object
}
代碼如下:
package com.isoft.po;
public class Response {
private static final String OK = "ok";
private static final String ERROR = "error";
private Meta meta;
private Object data;
public Response success() {
this.meta = new Meta(true, OK);
return this;
}
public Response success(Object data) {
this.meta = new Meta(true, OK);
this.data = data;
return this;
}
public Response success(Object data, String msg){
this.meta = new Meta(true, msg);
this.data = data;
return this;
}
public Response failure() {
this.meta = new Meta(false, ERROR);
return this;
}
public Response failure(String message) {
this.meta = new Meta(false, message);
return this;
}
public Meta getMeta() {
return meta;
}
public Object getData() {
return data;
}
public class Meta {
private boolean success;
private String message;
public Meta(boolean success) {
this.success = success;
}
public Meta(boolean success, String message) {
this.success = success;
this.message = message;
}
public boolean isSuccess() {
return success;
}
public String getMessage() {
return message;
}
}
}
4、jwt的token攔截器Interceptor
spring mvc的Interceptor實現類一般是繼承HandlerInterceptor接口並重寫preHandle、postHandle、afterCompletion的方法來實現的,這裏我們直接進行token的verify返回即可,具體代碼如下:
package com.isoft.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.isoft.util.JwtUtil;
import com.isoft.util.StringUtil;
/**
* jwt token攔截
* @author sd
*
*/
public class TokenInterceptor implements HandlerInterceptor{
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
String token = req.getHeader("Authorization");
if (StringUtil.isEmpty(token)) {
return false;
}
token = token.replace("Bearer ", "");
boolean isPass = JwtUtil.verify(token, JwtUtil.getUserId(token));
if (isPass) {
return true;
}
res.setStatus(401);
return false;
}
}
寫完這些還不行,需要將攔截器註冊到spring-mvc的config中:
<!-- mvc攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/users/login"/>
<bean class="com.isoft.interceptor.TokenInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
這裏使用mvc:exclude-mapping可以直接排除某個接口的攔截,比較方便。
5、mysql插入中文亂碼解決
使用ssm框架mybatis進行數據插入時,發現插入中文進去後數據有亂碼情況,除了設置數據庫編碼之外還解決不了問題的話,不妨看下mybatis的鏈接編碼設置,如果是db.properties的話,使用如下設置:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://ip:port/dbname?useUnicode=true&characterEncoding=utf-8
jdbc.username=username
jdbc.password=password
6、一個簡單的rest controller實例
package com.isoft.web.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.isoft.po.PageBean;
import com.isoft.po.Response;
import com.isoft.po.User;
import com.isoft.service.UserService;
import com.isoft.util.JwtUtil;
import com.isoft.util.StringUtil;
/**
* 用戶控制器類
*/
@RequestMapping("/users")
@RestController
public class UserController {
@Resource
private UserService userService;
/**
* 用戶註冊
*
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.CREATED)
public Response save(@RequestBody User user, HttpServletResponse res) throws Exception {
userService.add(user);
return new Response().success(user);
}
/**
* 用戶登錄
*
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "login", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public Response login(@RequestBody User user, HttpServletResponse res) throws Exception {
System.out.println(user);
User u = userService.login(user);
if (u != null) {
String token = JwtUtil.sign(u.getId());
u.setToken(token);
u.setHashedPassword("");
return new Response().success(u, "login success");
}
return new Response().failure("username or password wrong");
}
/**
* 用戶查詢帶分頁
*
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
public Response list(@RequestParam(value = "page", required = false, defaultValue = "1") String page,
@RequestParam(value = "rows", required = false, defaultValue = "10") String rows, User s_user, HttpServletResponse res)
throws Exception {
System.out.println(s_user);
PageBean pageBean = new PageBean(Integer.parseInt(page), Integer.parseInt(rows));
Map<String, Object> map = new HashMap<String, Object>();
map.put("userName", StringUtil.formatLike(s_user.getUserName()));
map.put("email", s_user.getemail());
map.put("start", pageBean.getStart());
map.put("size", pageBean.getPageSize());
List<User> userList = userService.find(map);
return new Response().success(userList);
}
/**
* 用戶更新
*
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@ResponseStatus(value = HttpStatus.OK)
public Response update(@PathVariable Integer id, @RequestBody User user, HttpServletResponse res) throws Exception {
user.setId(id);
System.out.println(user);
Integer count = userService.update(user);
if (count != 0) {
return new Response().success();
}
return new Response().failure();
}
/**
* 用戶刪除,支持批量
* @param id
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "/{ids}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
public Response delete(@PathVariable String ids, HttpServletResponse res) throws Exception {
String[] idsStrings = ids.split(",");
for (String id : idsStrings) {
userService.delete(Integer.parseInt(id));
}
return new Response().success();
}
/**
* 用戶詳情
* @param id
* @param user
* @param res
* @return
* @throws Exception
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
public Response getUser(@PathVariable Integer id, HttpServletResponse res) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
List<User> users = userService.find(map);
return new Response().success(users);
}
}
Java基於ssm框架的restful應用開發