Notes on writing ssm project

catalog

matters needing attention:

Output station scrambling

a link submitted as post

Form validation before submission

The onsubmit property is triggered when the form is submitted.

The onsubmit property is only available in the

Used in.
<form action="/demo/demo_form.asp" onsubmit="checkForm()">
//Last name: < input type = "text" name = "lname" > < br >
//Name: < input type = "text" name = "fname" > < br >
<input type="submit" value="Submit">
    
<script>
    function checkForm()
    {
    	alert("Form submitted!");
    }
</script>

Confirm before jump

Before you jump to the link, you need to determine whether the user has permission to open the page. If you do not have permission, a confirmation box will pop up to prompt "no permission". If you have permission, you can jump to the page directly.

Reference 1:
http://jingyan.baidu.com/article/425e69e6d043bebe15fc16db.html

a pop up the confirmation box when clicking the tag
Method 1:

< a href = "http://www.baidu.com" onclick = "return confirm ('are you sure you want to delete? ';" > [delete]</a>

Method 2:

<a onclick="confirm('Are you sure you want to jump?')?location.href='www.baidu.com':''" href="javascript:;">Baidu</a>

Reference 2:
http://blog.csdn.net/wujiangwei567/article/details/40352689

① Prompt in html tag

<a href="http://Www.baidu.com "onclick =" if (confirm ('confirm Baidu? '= = false) return false; "> Baidu</a>

Calling in js function

function foo(){
if(confirm("Confirm Baidu?")){
return true;
}
return false;
}

The corresponding label is changed to:

<a href="http://Www.baidu.com "onclick =" return foo(); "> Baidu</a>

matters needing attention:

Summary of the above references:

1. Jump method:

1> . place the connection in the a element's href attribute for page Jump

2> . use location.href for page Jump

c:if judgment

Is the string equal to the string in the field

1. < C: if test = "${student.sex eq 'male'} I'm a space" >

2. < C: if test = "${student. Sex EQ 'male'}" > < / C: if >

Be careful not to have extra space. Use eq keyword to judge equality

jsr303 validation form

@PostMapping("/editStudent")
    public String editStudentUI(@Valid @ModelAttribute Student student , BindingResult result, Model model){
        if (!bindResult(result, model)){
            return "error";
        }
        try {
            studentServiceImpl.update(student);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:/admin/showStudent";
    }
    
    
     public boolean bindResult(BindingResult result, Model model){
        if (result.hasErrors()){
            List<String> errors=new ArrayList<>();
            List<ObjectError> errorList = result.getAllErrors();
            for(ObjectError error : errorList){
                errors.add(error.getDefaultMessage());
            }
            model.addAttribute("error",errors);
            return false;
        } else{
            return true;
        }

    }
package com.system.pojo.base;

import org.hibernate.validator.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.util.Date;

public class Student {
    private Integer userid;

    @NotBlank(message = "Name cannot be empty")
    private String username;

    private String sex;

    private Date birthyear;

    private Date grade;

    private Integer collegeid;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex == null ? null : sex.trim();
    }

    public Date getBirthyear() {
        return birthyear;
    }

    public void setBirthyear(Date birthyear) {
        this.birthyear = birthyear;
    }

    public Date getGrade() {
        return grade;
    }

    public void setGrade(Date grade) {
        this.grade = grade;
    }

    public Integer getCollegeid() {
        return collegeid;
    }

    public void setCollegeid(Integer collegeid) {
        this.collegeid = collegeid;
    }

    @Override
    public String toString() {
        return "Student{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", sex='" + sex + '\'' +
                ", birthyear=" + birthyear +
                ", grade=" + grade +
                ", collegeid=" + collegeid +
                '}';
    }
}

Ajax

Parameters:

url: request address

type: request method (get request by default)

​ headers:

Data: parameter data key/value to be sent

Success: callback function after success

dataType: convert the data returned by the server to the specified type ("XML", "JSON", "text", "HTML", "JSON"...)

$.post

shiro

shiro comments

Common notes for Shiro

@RequiresPermissions: the current Subject is required to have one or more corresponding permissions when executing the annotated method.
@RequiresRoles("xxx"): the current Subject is required to have all roles when executing the annotated method, otherwise an AuthorizationException exception will be thrown.
@Requireauthentication: requires that the Subject has been verified in the current session when accessing or calling the annotated class / instance / method.

Tags used by Shiro in jsp

Need to introduce tags into jsp pages
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
label:
shiro:authenticated Certification is not about remembering me
shiro:notAuthenticated Not authenticated, including remember me to log in automatically
shiro:guest User is not authenticated when there is no RememberMe
shiro:user User authentication and at RememberMe
< Shiro: hasanyroles name = "abc, 123" > when there are abc or 123 roles
< Shiro: hasrole name = "abc" > have role abc
< Shiro: lacksrole name = "abc" > no role abc
< Shiro: haspermission name = "abc" > have permission resource abc < Shiro: lackspermission name = "abc" > do not have abc permission resource
shiro:principal Display user identity name
< Shiro: principal property = "username" / > display the property value in the user identity

shiro uses

Subject: equivalent to user

SecurityManager: equivalent to dispatcher Servlet

Realm: equivalent to DataSource

  • Import dependency

    <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.3</version>
            </dependency>
    ....
    //– shiro-all-1.3.2.jar 
    //– log4j-1.2.15.jar 
    //– slf4j-api-1.6.1.jar 
    //– slf4j-log4j12-1.6.1.jar
    
  • web.xml

    <!-- name And applicationContext.xml Corresponding to in bean Of id agreement -->
        <!--Shiro Interceptor shiro entrance-->
       <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <!-- The value defaults to false,Indicates that the lifecycle is created by SpringApplicationContext Administration,Set to true Means by ServletContainer Administration -->
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
    
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
  • configuration file

    1. Configure the custom realm class, (or auto scan) --- to create realm objects, such as myRealm
    2. To configure the DefaultWebSecurityManager, you need to use the realm object -- "to create the DefaultWebSecurityManager, such as: securityManager
    3. To configure ShiroFilterFactoryBean, you need to use the DefaultWebSecurityManager object -- "to create ShiroFilterFactoryBean, for example: shiroFilter (consistent with the filter name configuration in web.xml)

    URL permission takes the first matching priority

    <?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"
           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.xsd
    	">
    
        <!--Configure customization realm class-->
       <!-- <bean id="myRealm" class="com.system.realm.MyRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5"></property>
                    <property name="hashIterations" value="1024"></property>
                </bean>
            </property>
        </bean>-->
    
        <context:component-scan base-package="com.system.realm" />
    
        <!--Security Manager-->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="myRealm"/>
        </bean>
    
    
         <!--And web.xml Consistent filter name in-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- Shiro Core security interface of,This property is required -->
            <property name="securityManager" ref="securityManager"/>
            <!-- If the authentication fails, go to the configuration of the login page -->
            <!-- Require link at login(Login page address),It is not a required property. It will be found automatically by default Web Under the project root directory"/login.jsp"page -->
            <!--<property name="loginUrl" value="/login.jsp"/>
            <property name="successUrl" value="/index.jsp"/>-->
            <!-- If authority authentication fails, jump to the specified page -->
            <!--<property name="unauthorizedUrl" value="/login.htmls"/>-->
            <!-- Shiro Connection constraint configuration,Definition of filter chain -->
            <property name="filterChainDefinitions">
                <value>
                    <!--anon Indicates anonymous access without authentication and authorization-->
                    <!--authc Indicates that authentication is required and cannot be accessed without authentication-->
    
                    <!--When visiting login No authentication is required-->
                    /login = anon
    
                    <!--Configure static resources to be accessed anonymously-->
                    /css/** = anon
                    /dist/** = anon
                    /js/** = anon
                    /fonts/** = anon
    
                    /admin/** = authc,roles[admin]
                    /teacher/** = authc,roles[teacher]
                    /student/** = authc,roles[student]
    
    
                    /logout = logout
    
                    <!--Only the login interface can be accessed anonymously, and other paths can be accessed only by login authentication. No login to visit other paths to jump back to the login page-->
                    /**=authc
    
                </value>
            </property>
    
        </bean>
    
        <!-- life cycle -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    
    
        <!-- Enable shiro annotation -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
    
    </beans>
    
    
  • Custom realm

    package com.system.realm;
    
    import com.system.pojo.base.Role;
    import com.system.pojo.base.User;
    import com.system.service.RoleService;
    import com.system.service.UserLoginService;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @Description: Customized Realm
     * @Date 2020/3/21
     **/
    @Component
    public class MyRealm extends AuthorizingRealm {
    
        @Autowired
        private UserLoginService userLoginServiceImpl;
    
        @Autowired
        private RoleService roleServiceImpl;
    
        /**
         * @Description: Authority verification, obtaining identity information
         * @Param0: principalCollection
         * @Return: org.apache.shiro.authz.AuthorizationInfo
         **/
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            //1. Get current user name
            String  username = (String) getAvailablePrincipal(principalCollection);
    
            Role role = null;
    
            //2. Get user information from the database through the current user name
            try {
                User user = userLoginServiceImpl.findByName(username);
                //3. Get role information
                role=roleServiceImpl.findById(user.getRole());
            } catch (Exception e) {
                e.printStackTrace();
            }
            //4. Set roles and permissions for the current user
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //Set used to store character codes
            Set<String> r = new HashSet<String>();
            if (role != null) {
                r.add(role.getRolename());
                //5. Give the user role code to shiro
                info.setRoles(r);
            }
    
            return info;
        }
    
        /**
         * @Description: Authentication, called when login
         * @Param0: authenticationToken
         * @Return: org.apache.shiro.authc.AuthenticationInfo
         **/
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //user name
            String username = (String) token.getPrincipal();
            //password
            String password = new String((char[])token.getCredentials());
    
            //Get user information
            User user=null;
            try {
               user = userLoginServiceImpl.findByName(username);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //
            if (user == null) {
                //There is no such user name
                throw new UnknownAccountException();
            } else if (!password.equals(user.getPassword())) {
                //Password error
                throw new IncorrectCredentialsException();
            }
    
           /* ByteSource salt = ByteSource.Util.bytes(user.getSalt());//Salt value
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getName(),
                    user.getPassWord(),salt,getName());*/
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
    
            return authenticationInfo;
        }
    }
    
    
  • Authentication in controller

    1. Encapsulate user name, password
    2. Call the Subject.login method to log in. If there is no match, the AuthenticationException exception will appear
    3. Custom realm class, overriding doGetAuthenticationInfo() method
  • Get login information in controller

    1. SecurityUtils.getSubject() get subject
    2. subject.getPrincipal()
  • Get authorization information in controller

    1. subject.hasRole("xxx"), value in role code set
    2. Or subject.isPermitted()
  • controller code instance:

    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public String login(User user,Model model) throws Exception{
    
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
                                                                user.getPassword());
        //The object that the application code directly interacts with is subject, which represents the current "user"
        Subject subject = SecurityUtils.getSubject();
    
        subject.login(token);
        //If the user name cannot be obtained, the login fails. If the login fails, an exception will be thrown directly
        if (subject.hasRole("admin")) {
            return "redirect:/admin/showStudent";
        } else if (subject.hasRole("teacher")) {
            return "redirect:/teacher/showCourse";
        } else if (subject.hasRole("student")) {
            return "redirect:/student/showCourse";
        }
    
        return "redirect:/login";
    }
    
     //Get login information
    
        public User getUserInfo(){
            Subject subject = SecurityUtils.getSubject();
            String username= (String) subject.getPrincipal();
            User user=null;
            try {
                user= userLoginServiceImpl.findByName(username);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return user;
        }
    

Date conversion

In the date field of pojo class, add the annotation @ DateTimeFormat(pattern="yyyy/MM/dd") to write the specific date format according to your own situation;

The above is only valid for a po class. If you have many pojo classes with dates, write a date conversion class directly and register it in the configuration file of springMvc once and for all;

The conversion classes are as follows:

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Complete date binding, global, replace @ DateTimeFormat(pattern = "yyyy/MM/dd")
 */
public class DateConverter implements Converter<String, Date> {
    /**
     * Date conversion class
     */
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date convert(String source) {
        try {
            return simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
//        If the conversion fails, null will be returned;
        return null;
    }

}



Register to profile

<! -- configure custom parameter binding (date conversion) -- >
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService">
        <! -- write a custom converter -- >
        <property name="converters">
            <list>
                <! -- date conversion -- >
                <bean class="cn.hyc.utils.DateConverter"/>
            </list>
        </property>
    </bean>

 <! -- add to MVC comments -- >
<mvc:annotation-driven validator="validator" conversion-service="conversionService">

When using @ Request to bind JSON data parameters, you need to perform another operation on the date;

Otherwise, 400 bad request will be reported, and the request will not enter the background method;

Add @ JsonFormat(pattern="yyyy/MM/dd") to the get method of the date field of the pojo class;

json garbled

Solve the problem of output JSON garbled code

We found that even though we were web.xml The interceptor to solve the garbled code is configured in, but when the JSON is output to the foreground, the Chinese in JSON will be garbled;

This has nothing to do with the filter we configured. I guess it's inside the JSON converter. It defaults to ISO-8859 encoding, so when the filter gets the data, it's already scrambled data. It uses UTF8 encoding again, and finally it is still garbled, unless it can intelligently decode ISO-8859 first, and then UTF8 encoding.

To solve this problem, we need to springMvc.xml The JSON converter is configured in the MVC annotation tag in, and the code is UTF8;

<mvc:annotation-driven validator="validator" conversion-service="conversionService">
        <mvc:message-converters>
            <!-- Processing request return json The problem of Chinese character string garbled -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

Note: when binding the date, JSON adds comments on the field get method, and form adds comments on the field!

In the above methods, JSON is sent from the foreground, and then converted to an object, specifying the date format in JSON, so as to correctly convert the date object;

If, in turn, the object is converted to JSON, and the date type is directly converted, it will be converted to a string of numbers of the long type 1831389113131. We can also specify the format of the date in the JSON string: @ jsonfield (format = "yyyy MM DD")

  /**
     * JSON -> Object, specifying the date format in JSON for conversion to an object
     */
    @DateTimeFormat(pattern = "yyyy/MM/dd")
    /**
     * Object - JSON specifies the format of the date object in the converted String
     */
    @JSONField(format = "yyyy-MM-dd")
    private Date newsTime;

Reset button

It needs to be specified as: reset. Default submit

Path jump problem:

controller jump

  • redirect:/xxx jumps to / * * *, under the root path (if the root path is /, then the path after the jump is localhost/xxx
  • redirect:xxx Jump to the same level path request, that is, jump in the same controller (suppose that different controller classes have different request mapping annotation @ RequestMapping("/abc")..., after jump, the path localhost/abc/xxx can't realize the jump between controllers, because the request path (abc) of the controller class is different
  • forward: the same as direct

Page Jump

First, configure the view parser:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <! -- prefix and suffix of splicing view address -- >
     <property name="prefix" value="/WEB-INF/jsp/" />
     <property name="suffix" value=".jsp" />
</bean>

return "(want to jump to jsp path) xxx"

Jump path: localhost/xxx

For example: return "student/showCourse"; there is no slash in the front, but it has been added in the view parser

The actual JSP is located in D:\ideaFiles\Examination\src\main\webapp\WEB-INF\jsp\student\showCourse.jsp

PageHelper use

  1. rely on

     <!-- MyBatis Paging plug in -->
     <dependency>
         <groupId>com.github.pagehelper</groupId>
         <artifactId>pagehelper</artifactId>
         <version>5.1.2</version>
     </dependency>
    
  2. Configuration( 5.x.x Version)

    <?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>
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageInterceptor">
                <!-- config params as the following -->
                <property name="helperDialect" value="mysql"/>
            </plugin>
        </plugins>
    </configuration>
    
  3. Implementation, sql statement does not need to be changed

    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
    		
    		// 1. Call PageHelper's static method to enable paging
    		// This fully reflects the "non intrusive" design of PageHelper: the original query does not need to be modified
    		PageHelper.startPage(pageNum, pageSize);
    		
    		// 2. Execute query
    		List<Admin> list = adminMapper.selectAdminByKeyword(keyword);
    		// 3. Encapsulate into PageInfo object
    		PageInfo<Admin> adminPageInfo = new PageInfo<>(list);
    		return adminPageInfo;
    }
    

    The controller bar returns the pageinfo object with service and stores it in the model

Tags: Java Shiro JSON Apache JSP

Posted on Fri, 15 May 2020 01:44:37 -0400 by hchsk