Java基于ssm框架的restful应用开发

好几年都没写过java的应用了,这里记录下使用java ssm框架、jwt如何进行rest应用开发,文中会涉及到全局异常拦截处理、jwt校验、token拦截器等内容。

1、jwt工具类

直接贴代码了,主要包括jwt的sign、verify、decode三个方法,具体实现如下:

  1. package com.isoft.util;
  2. import java.util.Date;
  3. import com.auth0.jwt.JWT;
  4. import com.auth0.jwt.JWTVerifier;
  5. import com.auth0.jwt.algorithms.Algorithm;
  6. import com.auth0.jwt.interfaces.DecodedJWT;
  7. public class JwtUtil {
  8. private static final String SECRET = "xxxxx";
  9. private static final String USERID = "userId";
  10. private static final String ISSUER = "xxxx.com";
  11. // 过期时间7天
  12. private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000;
  13. // jwt sign
  14. public static String sign(Integer userId) {
  15. try {
  16. Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
  17. Algorithm algorithmHS = Algorithm.HMAC256(SECRET);
  18. return JWT.create().withClaim(USERID, userId).withExpiresAt(date).withIssuer(ISSUER).sign(algorithmHS);
  19. } catch (Exception e) {
  20. return null;
  21. }
  22. }
  23. // jwt verify
  24. public static boolean verify(String token, Integer userId) {
  25. try {
  26. Algorithm algorithmHS = Algorithm.HMAC256(SECRET);
  27. JWTVerifier verifier = JWT.require(algorithmHS).withClaim(USERID, userId).withIssuer(ISSUER).build();
  28. verifier.verify(token);
  29. return true;
  30. } catch (Exception e) {
  31. System.out.println(e);
  32. return false;
  33. }
  34. }
  35. // 返回token中的用户名
  36. public static Integer getUserId(String token) {
  37. try {
  38. DecodedJWT jwt = JWT.decode(token);
  39. return jwt.getClaim(USERID).asInt();
  40. } catch (Exception e) {
  41. return null;
  42. }
  43. }
  44. }

2、全局异常处理类

ssm中进行rest全局异常拦截处理主要用到RestControllerAdvice型注解类,直接贴代码:

  1. package com.isoft.exception;
  2. import org.springframework.http.HttpStatus;
  3. import org.springframework.http.converter.HttpMessageNotReadableException;
  4. import org.springframework.web.HttpRequestMethodNotSupportedException;
  5. import org.springframework.web.bind.annotation.ExceptionHandler;
  6. import org.springframework.web.bind.annotation.ResponseStatus;
  7. import org.springframework.web.bind.annotation.RestControllerAdvice;
  8. import com.isoft.po.Response;
  9. @RestControllerAdvice
  10. public class ExceptionAdvice {
  11. /**
  12. * 400 - Bad Request
  13. */
  14. @ResponseStatus(HttpStatus.BAD_REQUEST)
  15. @ExceptionHandler(HttpMessageNotReadableException.class)
  16. public Response handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
  17. return new Response().failure("could not read json");
  18. }
  19. /**
  20. * 405 - Method Not Allowed
  21. *
  22. * @param e
  23. * @return
  24. */
  25. @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
  26. @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
  27. public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
  28. return new Response().failure("request method not supported");
  29. }
  30. /**
  31. * 500 - Internal Server Error
  32. *
  33. * @param e
  34. * @return
  35. */
  36. @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  37. @ExceptionHandler(Exception.class)
  38. public Response handleException(Exception e) {
  39. System.err.println(e);
  40. return new Response().failure(e.getMessage());
  41. }
  42. }

这里主要拦截了405、400、500的n行yi'chang异常情况,可根据具体情况拓展。

3、自定义Response返回类

我们自定义的Response返回类格式如下:

  1. {
  2. "meta": {
  3. "success": true,
  4. "message": "ok"
  5. },
  6. data: Array or Object
  7. }

代码如下:

  1. package com.isoft.po;
  2. public class Response {
  3. private static final String OK = "ok";
  4. private static final String ERROR = "error";
  5. private Meta meta;
  6. private Object data;
  7. public Response success() {
  8. this.meta = new Meta(true, OK);
  9. return this;
  10. }
  11. public Response success(Object data) {
  12. this.meta = new Meta(true, OK);
  13. this.data = data;
  14. return this;
  15. }
  16. public Response success(Object data, String msg){
  17. this.meta = new Meta(true, msg);
  18. this.data = data;
  19. return this;
  20. }
  21. public Response failure() {
  22. this.meta = new Meta(false, ERROR);
  23. return this;
  24. }
  25. public Response failure(String message) {
  26. this.meta = new Meta(false, message);
  27. return this;
  28. }
  29. public Meta getMeta() {
  30. return meta;
  31. }
  32. public Object getData() {
  33. return data;
  34. }
  35. public class Meta {
  36. private boolean success;
  37. private String message;
  38. public Meta(boolean success) {
  39. this.success = success;
  40. }
  41. public Meta(boolean success, String message) {
  42. this.success = success;
  43. this.message = message;
  44. }
  45. public boolean isSuccess() {
  46. return success;
  47. }
  48. public String getMessage() {
  49. return message;
  50. }
  51. }
  52. }

4、jwt的token拦截器Interceptor

spring mvc的Interceptor实现类一般是继承HandlerInterceptor接口并重写preHandle、postHandle、afterCompletion的方法来实现的,这里我们直接进行token的verify返回即可,具体代码如下:

  1. package com.isoft.interceptor;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.http.HttpStatus;
  5. import org.springframework.web.servlet.HandlerInterceptor;
  6. import org.springframework.web.servlet.ModelAndView;
  7. import com.isoft.util.JwtUtil;
  8. import com.isoft.util.StringUtil;
  9. /**
  10. * jwt token拦截
  11. * @author sd
  12. *
  13. */
  14. public class TokenInterceptor implements HandlerInterceptor{
  15. @Override
  16. public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
  17. throws Exception {
  18. // TODO Auto-generated method stub
  19. }
  20. @Override
  21. public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
  22. throws Exception {
  23. // TODO Auto-generated method stub
  24. }
  25. @Override
  26. public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
  27. String token = req.getHeader("Authorization");
  28. if (StringUtil.isEmpty(token)) {
  29. return false;
  30. }
  31. token = token.replace("Bearer ", "");
  32. boolean isPass = JwtUtil.verify(token, JwtUtil.getUserId(token));
  33. if (isPass) {
  34. return true;
  35. }
  36. res.setStatus(401);
  37. return false;
  38. }
  39. }

写完这些还不行,需要将拦截器注册到spring-mvc的config中:

  1. <!-- mvc拦截器 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <mvc:mapping path="/**"/>
  5. <mvc:exclude-mapping path="/users/login"/>
  6. <bean class="com.isoft.interceptor.TokenInterceptor"></bean>
  7. </mvc:interceptor>
  8. </mvc:interceptors>

这里使用mvc:exclude-mapping可以直接排除某个接口的拦截,比较方便。

5、mysql插入中文乱码解决

使用ssm框架mybatis进行数据插入时,发现插入中文进去后数据有乱码情况,除了设置数据库编码之外还解决不了问题的话,不妨看下mybatis的链接编码设置,如果是db.properties的话,使用如下设置:

  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://ip:port/dbname?useUnicode=true&characterEncoding=utf-8
  3. jdbc.username=username
  4. jdbc.password=password

6、一个简单的rest controller实例

  1. package com.isoft.web.controller;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import javax.annotation.Resource;
  6. import javax.servlet.http.HttpServletResponse;
  7. import org.springframework.http.HttpStatus;
  8. import org.springframework.web.bind.annotation.PathVariable;
  9. import org.springframework.web.bind.annotation.RequestBody;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RequestMethod;
  12. import org.springframework.web.bind.annotation.RequestParam;
  13. import org.springframework.web.bind.annotation.ResponseStatus;
  14. import org.springframework.web.bind.annotation.RestController;
  15. import com.isoft.po.PageBean;
  16. import com.isoft.po.Response;
  17. import com.isoft.po.User;
  18. import com.isoft.service.UserService;
  19. import com.isoft.util.JwtUtil;
  20. import com.isoft.util.StringUtil;
  21. /**
  22. * 用户控制器类
  23. */
  24. @RequestMapping("/users")
  25. @RestController
  26. public class UserController {
  27. @Resource
  28. private UserService userService;
  29. /**
  30. * 用户注册
  31. *
  32. * @param user
  33. * @param res
  34. * @return
  35. * @throws Exception
  36. */
  37. @RequestMapping(value = "/", method = RequestMethod.POST)
  38. @ResponseStatus(value = HttpStatus.CREATED)
  39. public Response save(@RequestBody User user, HttpServletResponse res) throws Exception {
  40. userService.add(user);
  41. return new Response().success(user);
  42. }
  43. /**
  44. * 用户登录
  45. *
  46. * @param user
  47. * @param res
  48. * @return
  49. * @throws Exception
  50. */
  51. @RequestMapping(value = "login", method = RequestMethod.POST)
  52. @ResponseStatus(value = HttpStatus.OK)
  53. public Response login(@RequestBody User user, HttpServletResponse res) throws Exception {
  54. System.out.println(user);
  55. User u = userService.login(user);
  56. if (u != null) {
  57. String token = JwtUtil.sign(u.getId());
  58. u.setToken(token);
  59. u.setHashedPassword("");
  60. return new Response().success(u, "login success");
  61. }
  62. return new Response().failure("username or password wrong");
  63. }
  64. /**
  65. * 用户查询带分页
  66. *
  67. * @param user
  68. * @param res
  69. * @return
  70. * @throws Exception
  71. */
  72. @RequestMapping(value = "/", method = RequestMethod.GET)
  73. @ResponseStatus(value = HttpStatus.OK)
  74. public Response list(@RequestParam(value = "page", required = false, defaultValue = "1") String page,
  75. @RequestParam(value = "rows", required = false, defaultValue = "10") String rows, User s_user, HttpServletResponse res)
  76. throws Exception {
  77. System.out.println(s_user);
  78. PageBean pageBean = new PageBean(Integer.parseInt(page), Integer.parseInt(rows));
  79. Map<String, Object> map = new HashMap<String, Object>();
  80. map.put("userName", StringUtil.formatLike(s_user.getUserName()));
  81. map.put("email", s_user.getemail());
  82. map.put("start", pageBean.getStart());
  83. map.put("size", pageBean.getPageSize());
  84. List<User> userList = userService.find(map);
  85. return new Response().success(userList);
  86. }
  87. /**
  88. * 用户更新
  89. *
  90. * @param user
  91. * @param res
  92. * @return
  93. * @throws Exception
  94. */
  95. @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
  96. @ResponseStatus(value = HttpStatus.OK)
  97. public Response update(@PathVariable Integer id, @RequestBody User user, HttpServletResponse res) throws Exception {
  98. user.setId(id);
  99. System.out.println(user);
  100. Integer count = userService.update(user);
  101. if (count != 0) {
  102. return new Response().success();
  103. }
  104. return new Response().failure();
  105. }
  106. /**
  107. * 用户删除,支持批量
  108. * @param id
  109. * @param user
  110. * @param res
  111. * @return
  112. * @throws Exception
  113. */
  114. @RequestMapping(value = "/{ids}", method = RequestMethod.DELETE)
  115. @ResponseStatus(value = HttpStatus.OK)
  116. public Response delete(@PathVariable String ids, HttpServletResponse res) throws Exception {
  117. String[] idsStrings = ids.split(",");
  118. for (String id : idsStrings) {
  119. userService.delete(Integer.parseInt(id));
  120. }
  121. return new Response().success();
  122. }
  123. /**
  124. * 用户详情
  125. * @param id
  126. * @param user
  127. * @param res
  128. * @return
  129. * @throws Exception
  130. */
  131. @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  132. @ResponseStatus(value = HttpStatus.OK)
  133. public Response getUser(@PathVariable Integer id, HttpServletResponse res) throws Exception {
  134. Map<String, Object> map = new HashMap<String, Object>();
  135. map.put("id", id);
  136. List<User> users = userService.find(map);
  137. return new Response().success(users);
  138. }
  139. }

Java基于ssm框架的restful应用开发的更多相关文章

  1. 一款基于SSM框架技术的全栈Java web项目(已部署可直接体验)

    概述 此项目基于SSM框架技术的Java Web项目,是全栈项目,涉及前端.后端.插件.上线部署等各个板块,项目所有的代码都是自己编码所得,每一步.部分都有清晰的注释,完全不用担心代码混乱,可以轻松. ...

  2. 基于SSM框架的JavaWeb通用权限管理系统

    - - ->关注博主公众号[C you again],获取更多IT资源(IT技术文章,毕业设计.课程设计系统源码,经典游戏源码,HTML网页模板,PPT.简历模板,!!还可以投稿赚钱!!,点击查 ...

  3. 文献综述七:基于SSM的网上商城的开发与设计

    一.基本信息 标题:基于SSM的网上商城的开发与设计 时间:2018 出版源:Computer Knowledge and Technology 文件分类:对框架的研究 二.研究背景 为了解决现在电商 ...

  4. Java基于SSM在线学习系统设计与实现

                 Spring+SpringMVC+MyBatis+Bootstrap+Vue开发在线学习系统 本课题的主要内容是开发基于Java EE的在线学习平台,使用MVC经典开发模式. ...

  5. 基于SSM框架贺州学院校园二手交易平台设计与实现

    前言 这个是我当时的毕业论文,分享出来,给同学们参考. 绪论 随着中国新四大发明的诞生,网购成了千千万万网友们购物的新方式,新的购物方式促进商业的发展,但随着人们生活水平的提高,许多新购置的物品用了没 ...

  6. JAVA:ssm框架搭建

    文章来源:http://www.cnblogs.com/hello-tl/p/8328071.html 环境简介 : jdk1.7.0_25/jdk1.8.0_31  tomcat-7.0.81  m ...

  7. spring boot 简介(基于SSM框架的一个升级版本吧)

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过 ...

  8. 基于SSM框架配置多数据源

    项目基于ssm + maven,通过注解可以实现自动切换数据源. 一.pom.xml <?xml version="1.0" encoding="UTF-8&quo ...

  9. pageoffice实现网页打开编辑保存word文档(基于SSM框架)

    pageoffice是一款网页集成word.excel...等office工具 并不免费,但可以试用练习 SSM框架搭建过程就省略了 注意:由于谷歌/火狐升级,不支持插件嵌入,建议使用POBrowse ...

随机推荐

  1. ligerUI利用a标签下载文件

    一.利用WriteFile实现下载,并验证文件是否存在,将指定的文件直接写入HTTP响应输出流.注意:大型文件使用此方法可能导致异常.可以使用此方法的文件大小取决于 Web 服务器的硬件配置. (1) ...

  2. Swagger 导出API

    Swagger 导出API 这算是在博客园的第一篇博客吧,之后发的应该也会同步到博客园上. 此前的博客地址: https://blog.mytyiluo.cn Swagger简介 Swagger是一个 ...

  3. Android - "已安装了存在签名冲突的同名数据包",解决方法!

    错误提示:已安装了存在签名冲突的同名数据包. 解决方法:打开Android Studio,打开logcat,用usb线连接你出错的手机,识别出手机之后,在你的项目后面,点击“run”按钮,随后AS会提 ...

  4. String对象的简单方法(特别讲解length()方法的实现。

    length() 返回字符串中的字符数 charAt(index) 返回字符串中指定位置的字符 concat(s1)    将本字符串和字符串s1连接,返回一个新字符串 toUpperCase() 返 ...

  5. python 爬图 helloworld

    最近发现 吾志 上用户的头像都很个性,另外,对于没有把日记设为私密的用户,最后一天的日记是公开的,谁都可以查看. 所以,如果每天把所有可查看的日记爬一遍,那么-- 哈哈 以前对爬虫只是了解一点点,没有 ...

  6. 2018 Multi-University Training Contest 4

    累惹. B. Harvest of Apples 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6333 题意:求∑(i=0,m) C(n,m). 分 ...

  7. docker镜像基本操作一

    获取镜像 首先说明一下如何从Docker hub中获取高质量的镜像,从Docker镜像库获取镜像的命令是docker pull .其命令格式为: docker pull [选项] [Docker Re ...

  8. python 初步认识Flask

    1.简介 flask 问题一:  访问百度的流程? a. 客户端: 发送请求报文,  请求行, 请求头, 请求体 b.服务端: 解析请求的报文, 解析域名, 进行路由匹配分发找到对应的视图函数, 打包 ...

  9. checkbox选中事件

    在前端中,往往需要根据后台数据的返回选中多选框.可以根据后台返回的数据转化为数组,然后又val([数组])进行选中. 例子: html代码: <!DOCTYPE html> <htm ...

  10. javaWeb知识点学习(一)

    1.静态页面的传递过程 在静态WEB程序中,客户端使用WEB浏览器(IE.FireFox等)经过网络(Network)连接到服务器上,使用HTTP协议发起一个请求(Request),告诉服务器我现在需 ...