当前位置: 首页 > news >正文

网站开发的关键技术有哪些备案中的网站信息怎么填

网站开发的关键技术有哪些,备案中的网站信息怎么填,html做网站需要服务器吗,网站维护和网页维护区别网络安全的重要性不言而喻#xff0c;如今早已不是以前随便弄个http请求就能爬到数据的时代#xff0c;而作为一个架构师#xff0c;网络安全必须在产品开发之初就考虑好。因为在产品开发的后期#xff0c;一方面是客户增多#xff0c;压力变大#xff0c;可供利用的时间…网络安全的重要性不言而喻如今早已不是以前随便弄个http请求就能爬到数据的时代而作为一个架构师网络安全必须在产品开发之初就考虑好。因为在产品开发的后期一方面是客户增多压力变大可供利用的时间也会变少另一方面随着时间的推移项目越发庞大这个时候想要在开发继续推进的同时来调整架构带来的影响不可谓不大。 同时对于多用户系统来说必然涉及到用户角色管理不同的用户不可能具有相同的权限而如果要通过硬编码来实现那工作量可就大了而且配置起来也极其不灵活二通过架构方式来编写这些框架代码那也是不小的工程量而且对架构师水平要求也不低。 所幸Springboot就自带了安全模块我们可以在前期设计的时候很轻松的引入这些模块。如果这些模块让我们自己来写一遍自然是很痛苦的更主要的是你写完了不一定有他的好Web开发最好的地方在于他有太多的脚手架可直接使用。在这里我们需要用到的就是SpringSecurity及JWT。 JWT JWT是JSON WEB TOKEN的缩写它是基于 RFC 7519 标准定义的一种可以安全传输的的JSON对象由于使用了数字签名所以是可信任和安全的。 JWT的组成 我们先来看一个JWT加密后的token eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImNyZWF0ZWQiOjE1NTY3NzkxMjUzMDksImV4cCI6MTU1NzM4MzkyNX0.d-iki0193X0bBOETf2UN3r3PotNIEAV7mzIxxeI5IxFyzzkOZxS0PGfF_SK6wxCv2K8S0cZjMkv6b5bCqc0VBw只是看这个字符串会觉得一脸懵逼它实际上是遗传加密过的字符串我们可以在jwt.io/解析出它的原文 在右边的解析中给出了他内容解析说明它是由三部分构成 JWT token的格式header.payload.signature header中用于存放签名的生成算法 {alg: HS512}payload中用于存放用户名、token的生成时间和过期时间 {sub:admin,created:1489079981393,exp:1489684781}signature为以header和payload生成的签名一旦header和payload被篡改验证将失败 //secret为加密算法的密钥 String signature HMACSHA512(base64UrlEncode(header) . base64UrlEncode(payload),secret)既然jwt是可以被解析的那么它到底解决了什么问题呢我们一般设计授权模块就是做一个加密的token然后让客户端在每次请求的时候都带上这个token我们会对token解析并校验是否合法不合法就会拒绝服务jwt健康相当于把这部分功能给我们做了 用户调用登录接口登录成功后获取到JWT的token之后用户每次调用接口都在http的header中添加一个叫Authorization的头值为JWT的token后台程序通过对Authorization头中信息的解码及数字签名校验来获取其中的用户信息从而实现认证和授权。 环境 引入安全模块主要用到两个模块一个是springboot自带的security模块另一个是jwt模块。在实际项目实战用为了不重复造轮子还需要应用hutool这个三方依赖。这个依赖带了一些工具类方法有点像Android的Xutil可以为我们开发节省很多时间在这里主要是用来做加解密。如果你有其他更合适的只要能达到效果就行。 依赖 在pom.xml中添加项目依赖 !--SpringSecurity依赖配置-- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId /dependency !--Hutool Java工具包-- dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion4.5.7/version /dependency !--JWT(Json Web Token)登录支持-- dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.9.0/version /dependency然后我们需要一些功能性的工具根据我们的业务我们需要三个功能 根据用户信息生成对应的tokengenerateToken(UserDetails userDetails)用户用token请求后我们还需要解析这个token因此需要一个解析的方法getUserNameFromToken(String token)解析token后需要判断是否有效这里主要是做通用有效性判断validateToken(String token, UserDetails userDetails) 好了我们把这个实现下 package org.lange.mall.common.util;import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component;import java.util.Date; import java.util.HashMap; import java.util.Map;/*** JwtToken生成的工具类* JWT token的格式header.payload.signature* header的格式算法、token的类型* {alg: HS512,typ: JWT}* payload的格式用户名、创建时间、生成时间* {sub:wang,created:1489079981393,exp:1489684781}* signature的生成算法* HMACSHA512(base64UrlEncode(header) . base64UrlEncode(payload),secret)*/ Component public class JwtTokenUtil {private static final Logger LOGGER LoggerFactory.getLogger(JwtTokenUtil.class);private static final String CLAIM_KEY_USERNAME sub;private static final String CLAIM_KEY_CREATED created;Value(${jwt.secret})private String secret;Value(${jwt.expiration})private Long expiration;/*** 根据负载生成JWT的token*/private String generateToken(MapString, Object claims) {return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate()).signWith(SignatureAlgorithm.HS512, secret).compact();}/*** 从token中获取JWT中的负载*/private Claims getClaimsFromToken(String token) {Claims claims null;try {claims Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();} catch (Exception e) {LOGGER.info(JWT格式验证失败:{}, token);}return claims;}/*** 生成token的过期时间*/private Date generateExpirationDate() {return new Date(System.currentTimeMillis() expiration * 1000);}/*** 从token中获取登录用户名*/public String getUserNameFromToken(String token) {String username;try {Claims claims getClaimsFromToken(token);username claims.getSubject();} catch (Exception e) {username null;}return username;}/*** 验证token是否还有效** param token 客户端传入的token* param userDetails 从数据库中查询出来的用户信息*/public boolean validateToken(String token, UserDetails userDetails) {String username getUserNameFromToken(token);return username.equals(userDetails.getUsername()) !isTokenExpired(token);}/*** 判断token是否已经失效*/private boolean isTokenExpired(String token) {Date expiredDate getExpiredDateFromToken(token);return expiredDate.before(new Date());}/*** 从token中获取过期时间*/private Date getExpiredDateFromToken(String token) {Claims claims getClaimsFromToken(token);return claims.getExpiration();}/*** 根据用户信息生成token*/public String generateToken(UserDetails userDetails) {MapString, Object claims new HashMap();claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());claims.put(CLAIM_KEY_CREATED, new Date());return generateToken(claims);}/*** 判断token是否可以被刷新*/public boolean canRefresh(String token) {return !isTokenExpired(token);}/*** 刷新token*/public String refreshToken(String token) {Claims claims getClaimsFromToken(token);claims.put(CLAIM_KEY_CREATED, new Date());return generateToken(claims);} } 上面用到了Component注解这个注解和ServiceController使用类似都是在需要使用的类中通过Autowired连接就能自动使用。这其实是SpringBoot的Bean管理机制在组件的使用中根本不需要去new对象。 配置SpringSecurity 和前面我们了解的Springboot的MybatisSwagger一样使用SpringSecurity需要添加配置类自动化配置。这里需要用到三个额外的注解 Configuration Autowired EnableWebSecurity EnableGlobalMethodSecurity(prePostEnabled true) Bean 前面两个我们前面用过了。EnableWebSecurity作为Springboot自带的一个注解他的作用就是让项目运行的时候启动安全模块。而EnableGlobalMethodSecurity同时这个注解为我们提供了prePostEnabled 、securedEnabled 和 jsr250Enabled 三种不同的机制来实现同一种功能。 Autowired不仅仅可以用在对象实例化上给成员变量的使用提供getset方法还可以注解在方法上而Bean如果注解在一个返回对象的方法上调用的时候可以直接使用该对象而不用调用方法来获取对象。 对于SpringSecurity的配置我们需要创建一个配置类SecurityConfig.java package org.lange.mall.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;/*** SpringSecurity的配置*/ Configuration EnableWebSecurity EnableGlobalMethodSecurity(prePostEnabled true) public class SecurityConfig {Autowiredprivate RestfulAccessDeniedHandler restfulAccessDeniedHandler;Autowiredprivate RestAuthenticationEntryPoint restAuthenticationEntryPoint;Autowiredprivate IgnoreUrlsConfig ignoreUrlsConfig;BeanSecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {ExpressionUrlAuthorizationConfigurerHttpSecurity.ExpressionInterceptUrlRegistry registry httpSecurity.authorizeRequests();//不需要保护的资源路径允许访问for (String url : ignoreUrlsConfig.getUrls()) {registry.antMatchers(url).permitAll();}//允许跨域请求的OPTIONS请求registry.antMatchers(HttpMethod.OPTIONS).permitAll();httpSecurity.csrf()// 由于使用的是JWT我们这里不需要csrf.disable().sessionManagement()// 基于token所以不需要session.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().anyRequest()// 除上面外的所有请求全部需要鉴权认证.authenticated();// 禁用缓存httpSecurity.headers().cacheControl();// 添加JWT filterhttpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);//添加自定义未授权和未登录结果返回httpSecurity.exceptionHandling().accessDeniedHandler(restfulAccessDeniedHandler).authenticationEntryPoint(restAuthenticationEntryPoint);return httpSecurity.build();}Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}Beanpublic JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {return new JwtAuthenticationTokenFilter();}} 在上面的配置类里面最重要的两个方法filterChain和passwordEncoder这两个是提供给系统调用的。一个是用来创建拦截器配置这个拦截器决定了请求放行规则这个怎么理解呢比如某些分享链接或者用户还没有登陆的时候那他是什么权限也没有的。如果不给放行那连入口都没有谈何使用。这就是放行的作用同时一些外部的Api调用也需要在这里配置。 把这个说明白那一串代码就很好理解了。我们要放行某些资源路径要配置一些跨域请求然后这里还禁用了缓存添加了一个token过滤器用来过滤不正常的请求。然后就是配置了授权不通过的返回大概就是这些了。这里资源路劲比较多所以单独放在类IgnoreUrlsConfig中为了演示方便这个类中没啥东西 package org.lange.mall.config.security;import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration;import java.util.ArrayList; import java.util.List;Getter Setter Configuration ConfigurationProperties(prefix secure.ignored) public class IgnoreUrlsConfig {private ListString urls new ArrayList(); } 然后我们来看下授权过滤器要怎么写JwtAuthenticationTokenFilter.java package org.lange.mall.component;import org.lange.mall.common.util.JwtTokenUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {//继承了每次请求一次的过滤器还有其他的过滤器可以使用private static final Logger LOGGER LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);Autowiredprivate UserDetailsService userDetailsService;Autowiredprivate JwtTokenUtil jwtTokenUtil;Value(${jwt.tokenHeader})private String tokenHeader;Value(${jwt.tokenHead})private String tokenHead;Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws ServletException, IOException {// 拿到请求头因为验证信息都放在通用请求头里面的String authHeader request.getHeader(this.tokenHeader);// 判断是否有tokenif (authHeader ! null authHeader.startsWith(this.tokenHead)) {//提取出来tokenString authToken authHeader.substring(this.tokenHead.length());// The part after Bearer // token中包含username我们提取出来String username jwtTokenUtil.getUserNameFromToken(authToken);LOGGER.info(checking username:{}, username);// 能提取到username 并且开了安全验证就继续if (username ! null SecurityContextHolder.getContext().getAuthentication() null) {// 通过这个username在service里面查询用户详细UserDetails userDetails this.userDetailsService.loadUserByUsername(username);// 判断token数据和用户详情是否对的上切token没有过期if (jwtTokenUtil.validateToken(authToken, userDetails)) {//校验通过更新用户详细UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));LOGGER.info(authenticated user:{}, username);//告诉安全机制验证通过SecurityContextHolder.getContext().setAuthentication(authentication);}}}// 执行过滤逻辑chain.doFilter(request, response);} } 如果没有通过验证那我们要禁止他访问返回通用禁止响应这个很好理解。 package org.lange.mall.component;import cn.hutool.json.JSONUtil; import org.lange.mall.common.api.CommonResult; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** 当访问接口没有权限时自定义的返回结果* 这里是通用禁止响应*/ Component public class RestfulAccessDeniedHandler implements AccessDeniedHandler {Overridepublic void handle(HttpServletRequest request,HttpServletResponse response,AccessDeniedException e) throws IOException, ServletException {response.setCharacterEncoding(UTF-8);response.setContentType(application/json);response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));response.getWriter().flush();} } 如果用户没有登陆就请求了我们不应该返回禁止而是返回未授权的提示这个编码和禁止差不多只不过需要实现的接口不一样 package org.lange.mall.component;import cn.hutool.json.JSONUtil; import org.lange.mall.common.api.CommonResult; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component;import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** 当未登录或者token失效访问接口时自定义的返回结果*/ Component public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {response.setCharacterEncoding(UTF-8);response.setContentType(application/json);response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage())));response.getWriter().flush();} }到这里已经完成及安全模块的配置不过我们前面写的配置好像和用户角色管理没有关系因为我们没有实现我们自己的用户管理服务呀那我们要来实现以下MallSecurityConfig.java package org.lange.mall.config.security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException;/*** 自定义配置用于配置如何获取用户信息*/ Configuration public class MallSecurityConfig {Autowiredprivate UmsAdminService adminService;Beanpublic UserDetailsService userDetailsService() {//获取登录用户信息return new UserDetailsService() {Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {AdminUserDetails admin adminService.getAdminByUsername(username);if (admin ! null) {return admin;}throw new UsernameNotFoundException(用户名或密码错误);}};} }顺便实现对应的bean和service这个bean要实现Springboot的UserDetails不然会找不到。我们后续是可以扩展这个用户信息类的这里为了掩饰就不扩展了。 package org.lange.mall.data;import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection; import java.util.List; import java.util.stream.Collectors;/*** SpringSecurity用户信息封装类*/ Data EqualsAndHashCode(callSuper false) Builder public class AdminUserDetails implements UserDetails {private String username;private String password;private ListString authorityList;Overridepublic Collection? extends GrantedAuthority getAuthorities() {return this.authorityList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());}Overridepublic String getPassword() {return this.password;}Overridepublic String getUsername() {return this.username;}Overridepublic boolean isAccountNonExpired() {return true;}Overridepublic boolean isAccountNonLocked() {return true;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return true;} } 然后就是对应的service面向接口编程是个好习惯有利于规范化。UmsAdminService.java: package org.lange.mall.service.impl;import cn.hutool.core.collection.CollUtil; import lombok.extern.slf4j.Slf4j; import org.lange.mall.common.util.JwtTokenUtil; import org.lange.mall.data.AdminUserDetails; import org.lange.mall.service.UmsAdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service;import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;Slf4j Service public class UmsAdminServiceImpl implements UmsAdminService {/*** 存放默认用户信息*/private ListAdminUserDetails adminUserDetailsList new ArrayList();// 存放默认资源信息//private ListUmsResource resourceList new ArrayList();Autowiredprivate JwtTokenUtil jwtTokenUtil;Autowiredprivate PasswordEncoder passwordEncoder;PostConstructprivate void init(){adminUserDetailsList.add(AdminUserDetails.builder().username(admin).password(passwordEncoder.encode(123456)).authorityList(CollUtil.toList(brand:create,brand:update,brand:delete,brand:list,brand:listAll)).build());adminUserDetailsList.add(AdminUserDetails.builder().username(macro).password(passwordEncoder.encode(123456)).authorityList(CollUtil.toList(brand:listAll)).build());/*resourceList.add(UmsResource.builder().id(1L).name(brand:create).url(/brand/create).build());resourceList.add(UmsResource.builder().id(2L).name(brand:update).url(/brand/update/**).build());resourceList.add(UmsResource.builder().id(3L).name(brand:delete).url(/brand/delete/**).build());resourceList.add(UmsResource.builder().id(4L).name(brand:list).url(/brand/list).build());resourceList.add(UmsResource.builder().id(5L).name(brand:listAll).url(/brand/listAll).build());*/}Overridepublic AdminUserDetails getAdminByUsername(String username) {ListAdminUserDetails findList adminUserDetailsList.stream().filter(item - item.getUsername().equals(username)).collect(Collectors.toList());if(CollUtil.isNotEmpty(findList)){return findList.get(0);}return null;}// Override // public ListUmsResource getResourceList() { // return resourceList; // }Overridepublic String login(String username, String password) {String token null;try {UserDetails userDetails getAdminByUsername(username);if(userDetailsnull){return token;}if (!passwordEncoder.matches(password, userDetails.getPassword())) {throw new BadCredentialsException(密码不正确);}UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());SecurityContextHolder.getContext().setAuthentication(authentication);token jwtTokenUtil.generateToken(userDetails);} catch (AuthenticationException e) {log.warn(登录异常:{}, e.getMessage());}return token;} }到这里业务相关的鉴权我们写完了但是我们还没有接入到接口中也就是用户要从哪里请求我们要定义好。我们来实现以下登录接口通常的登录逻辑是用户拿用户名和密码来登录登录成功我们返回token这个时候用户就能用这个token去请求他想要的资源了。如果用户没有登陆就去请求就会提示未登录现在我们来实现下。 先定义接口控制器UmsAdminController.java,就两个方法一个登录一个请求资源列表。在此之前我们把资源的这个类定义一下 package org.lange.mall.data;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode;import java.util.Date;/*** 后台资源表*/ Data EqualsAndHashCode(callSuper false) ApiModel(valueUmsResource对象, description后台资源表) Builder public class UmsResource{private Long id;ApiModelProperty(value 创建时间)private Date createTime;ApiModelProperty(value 资源名称)private String name;ApiModelProperty(value 资源URL)private String url;ApiModelProperty(value 描述)private String description;ApiModelProperty(value 资源分类ID)private Long categoryId;} 然后要把service中获取资源列表的方法放开一下前面被我注释了UmsAdminController.java package org.lange.mall.controller;import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.tags.Tag; import org.lange.mall.common.api.CommonResult; import org.lange.mall.data.UmsResource; import org.lange.mall.service.UmsAdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; 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 java.util.HashMap; import java.util.List; import java.util.Map;Controller Api(tags UmsAdminController) Tag(name UmsAdminController, description 后台用户管理) RequestMapping(/admin) public class UmsAdminController {Autowiredprivate UmsAdminService adminService;Value(${jwt.tokenHeader})private String tokenHeader;Value(${jwt.tokenHead})private String tokenHead;ApiOperation(value 登录以后返回token)RequestMapping(value /login, method RequestMethod.POST)ResponseBodypublic CommonResult login(RequestParam String username, RequestParam String password) {String token adminService.login(username, password);if (token null) {return CommonResult.validateFailed(用户名或密码错误);}MapString, String tokenMap new HashMap();tokenMap.put(token, token);tokenMap.put(tokenHead, tokenHead);return CommonResult.success(tokenMap);}ApiOperation(value 请求资源列表)RequestMapping(value /resourceList, method RequestMethod.POST)ResponseBodypublic CommonResultListUmsResource resourceList() {ListUmsResource resourceList adminService.getResourceList();return CommonResult.success(resourceList);} } 然后就是运行测试看效果。
http://www.hkea.cn/news/14384095/

相关文章:

  • 织梦做的网站首页出现空白潮阳网站制作
  • 安徽省建设厅网站职称申报wordpress首页调用指定分类
  • 河南城乡住房和建设厅网站网站模版设计
  • 住房和城乡建设部网站主页怎么切图做网站
  • 免费网站软件大全旅游公司网站建设方案
  • 平台网站设计做网站优化的关键词怎么设置
  • 整站优化和关键词优化的区别江苏seo策略
  • 石家庄网站seo服务网站设计方案图
  • 自助搭建网站如何选择低价网站建设
  • 合肥做企业建网站那家好南京门户网站建设
  • 苏州市网站建设手机网站制作移动高端网站建设
  • 初学者做网站的软件邯郸论坛官网
  • 公司做网站怎么样钉钉小程序开发工具
  • 有没有做丝网的网站呀怎么做网站图片链接
  • 山西省住房和城乡建设厅官方网站如何seo网站
  • 网站做的好不好看什么招工平台网
  • 结构设计网站网络服务有点问题
  • 绍兴市住房与城乡建设厅网站可以免费开店的平台有哪些
  • 做网站做的好的公司有哪些平台商城网站开发
  • 石家庄网站推广专家wordpress 工作流程
  • 有什么可以做兼职的正规网站wordpress实名
  • 安庆网站建设aqwzjs怎样自己免费做一个网址
  • 国外网站做网站主播卡片式主题wordpress
  • 网站怎么做才会有收录如何向百度提交自己的网站
  • 职业教育网站建设高水平的番禺网站建设
  • 阳江网站建设 公司做公众号app,网站,app
  • 网站为什么要icp备案建站之星视频
  • 什么网站可以查询企业信息网站制作需要哪些软件有哪些
  • 外链生成网站wordpress焦点图
  • 繁体商城网站模板自己如何建设刷赞网站